Variable Limits in Unions

Hey All,
ich habe vier Tabellen (Kunden, Lieferanten, Personen, Autos) die ich via Unions Abfrage und in jQuery-Catcomplete nutze.
Ingesamt sollen ca. 20 Ergebnisse zurückgeliefert werden.

Derzeit arbeite ich mit festen Limits ( LIMIT = 5 ). Das jedoch etwas unpraktisch.
Wenn in der unlimitierten Ergebnismenge beispielsweise 10 Kunden, 2 Lieferanten, 1 Person und 1 Auto vorkommt werden nur 5 Kunden angezeigt.
Deshalb möchte ich die Limits variabel gestalten. (Es sollen 10 Kunden statt 5 angezeigt werden.)
Die Liste soll jedoch nicht länger als 20 werden.

Ich habe es sehr kompliziert mit Unterabfragen gelöst und dann durch vier dividiert.
Kommt in einem Union jedoch kein Ergebnis vor ( z.B. kein Auto gefunden ) stimmt der Algorithmus nicht mehr.

Hat jemand eine Idee bzw Lösung für diese Problem?

CREATE OR REPLACE FUNCTION random_string( length INT ) RETURNS TEXT AS
$$
DECLARE
  chars TEXT[] := '{a,b,c,d,e,f}';
  result TEXT := '';
  i INT := 0;
BEGIN
  END IF;
  FOR i IN 1..length LOOP
    result := result || chars[1 + random() * ( array_length( chars, 1 ) -1 )];
  END LOOP;
  RETURN result;
END;
$$ LANGUAGE PLPGSQL;

DROP FUNCTION IF EXISTS ranCharInsert( TEXT, INT, TEXT );
CREATE OR REPLACE FUNCTION ranCharInsert( tableName TEXT, n INT, columnname TEXT DEFAULT 'name' ) 
  RETURNS VOID AS    
  $$
DECLARE
BEGIN
    FOR i IN 1..n LOOP
      EXECUTE 'INSERT INTO '|| tableName ||' ( '|| columnname || ' ) SELECT random_string(10)';
    END LOOP;
END;
$$ LANGUAGE PLPGSQL;

DROP TABLE IF EXISTS kunde; 
CREATE TABLE kunde(
  id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  name TEXT
);

DROP TABLE IF EXISTS lieferant; 
CREATE TABLE lieferant(
  id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  name TEXT
);

DROP TABLE IF EXISTS person; 
CREATE TABLE person(
  id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  name TEXT
);

DROP TABLE IF EXISTS car; 
CREATE TABLE car(
  id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  licenseplate TEXT
);


SELECT ranCharInsert( 'kunde', 80 );
SELECT ranCharInsert( 'lieferant', 40 );
SELECT ranCharInsert( 'person', 20 );
SELECT ranCharInsert( 'car', 30, 'licenseplate' );

( SELECT name AS label, 'kunde' AS categorie FROM kunde WHERE name ILIKE '%da%' LIMIT 5 )
UNION 
( SELECT name AS label, 'lieferant' AS categorie FROM lieferant WHERE name ILIKE '%da%' LIMIT 5 )  
UNION 
( SELECT name AS label, 'person' AS categorie FROM person WHERE name ILIKE '%da%' LIMIT 5 ) 
UNION 
( SELECT licenseplate AS label, 'Auto' AS categorie FROM car WHERE licenseplate ILIKE '%da%' LIMIT 5 ) 
ORDER BY categorie;

( SELECT count(*)::INT FROM ( SELECT name FROM kunde WHERE name ILIKE '%da%' ) AS k );



Dank und Gruß
Ronny

dann mach Dein UNION ohne LIMIT und dann das Limit auf das Ergebniss der 4 UNIONS. Vorher vielleicht noch durchmischen.

Ok, sehr einfacher Ansatz. (ohne rechnen…)
Doch wie mische ich??

postgres=# with bla as (select * from generate_series(1,10) s) select * from bla;
 s  
----
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
(10 rows)

postgres=# with bla as (select * from generate_series(1,10) s) select * from bla order by random();
 s  
----
  9
  4
  2
  5
  3
  8
 10
  6
  1
  7
(10 rows)

postgres=# 

Dieses Thema wurde automatisch 60 Tage nach der letzten Antwort geschlossen. Es sind keine neuen Antworten mehr erlaubt.