2017-12-04 9 views
0

In einer MySQL-Datenbank habe ich 3 Tabellen: customers, projects und tasks. Für eine Suche, die ich implementiere, möchte ich alle 3 Tabellen durchsuchen und gefundene Übereinstimmungen auswählen. Das Problem ist, dass ich die Anzahl der von MySQL zurückgegebenen Ergebnisse gleichermaßen einschränken möchte.MySQL - SELECT gleiche Menge von jedem in UNION von insgesamt LIMIT

Dies ist ein Beispiel mit der Abfrage, die ich derzeit haben:

SELECT id, title, type 
FROM (
    (
    SELECT id, title, 'customer' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score 
    FROM customers 
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) 
    ) 
    UNION DISTINCT 
    (
    SELECT id, title, 'project' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score 
    FROM projects 
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) 
    ) 
    UNION DISTINCT 
    (
    SELECT id, title, 'task' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score 
    FROM tasks 
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) 
    ) 
) res 
LIMIT 6; 

In diesem Beispiel möchte ich die Ergebnisse begrenzen 6.

Meine gewünschte Endresultat für dieses Beispiel ist die folgende:

1) Wenn alle Tabellen mindestens 2 Ergebnisse haben, zeigen Sie jeweils 2 Ergebnisse an.

id  title      type 
20  'First test customer'  'customer' 
22  'Test customer 2'   'customer 
48  'A project for testing' 'project' 
17  'Test Project'    'project' 
1  'Task test'    'task' 
2  'Second test'    'task' 

2) Wenn eine Tabelle keine Ergebnisse hat, zeigen 3 Ergebnisse für jede der zwei anderen Tabellen. (Wenn nur eine Tabelle, die Ergebnisse hat, zeigen 6 Ergebnisse für diese Tabelle.)

id  title      type 
20  'First test customer'  'customer' 
22  'Test customer 2'   'customer 
56  'Customer test 56'   'customer' 
1  'Task test'    'task' 
2  'Second test'    'task' 
3  'Test task'    'task' 

3) Wenn 2 der Tabellen haben mehr als 2 Ergebnisse, und die dritte Tabelle hat nur 1 Ergebnis, zeigen 3 Ergebnisse für eine der Tabellen mit genügend Ergebnissen, 2 Ergebnisse für das andere der beiden und 1 für die Tabelle mit nur 1 Ergebnis.

id  title      type 
20  'First test customer'  'customer' 
48  'A project for testing' 'project' 
17  'Test Project'    'project' 
34  'Testing project'   'project' 
1  'Task test'    'task' 
2  'Second test'    'task' 

Kann mir bitte jemand dabei helfen?

Vielen Dank im Voraus!

Antwort

1

Sie könnten für jedes einzelne SELECT eine Zeilennummer verwenden und dann das UNION mit diesem berechneten Feld bestellen, um die Ergebnisse der einzelnen Abfragen auszugleichen (ich habe diesen Code nicht getestet, bitte als Ausgangspunkt):

SET @rank1=0; 
SET @rank2=0; 
SET @rank3=0; 
SELECT id, title, type, rank 
FROM (
    (

    SELECT @rank1:[email protected]+1 AS rank, id, title, 'customer' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score 
    FROM customers 
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) 
    ) 
    UNION DISTINCT 
    (

    SELECT @rank2:[email protected]+1 AS rank, id, title, 'project' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score 
    FROM projects 
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) 
    ) 
    UNION DISTINCT 
    (

    SELECT @rank3:[email protected]+1 AS rank, id, title, 'task' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score 
    FROM tasks 
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) 
    ) 
) res 
ORDER BY rank 
LIMIT 6; 
+0

Danke für die Antwort, aber MySQL scheint mich nicht das 'SET' (Syntaxfehler) verwenden zu lassen. Hast du eine Chance, warum? – DylanVB

+0

@DylanVB Ich habe die Antwort bearbeitet: wahrscheinlich sollte die Set-Deklaration-Anweisung außerhalb der Auswahl – kiks73

+0

Deklarieren der Variablen außerhalb der Abfrage tatsächlich funktioniert. Wäre es möglich, die Variablen in der Abfrage festzulegen? – DylanVB

1

um das @ kiks73 Ergebnis in einer Abfrage haben, ohne Variablen zu deklarieren @rankX Sie eine (SELECT @rankX:=0) AS t zu der von Klausel hinzufügen können. wie folgt:

SELECT id, title, type, rank 
FROM (
    (

    SELECT @rank1:[email protected]+1 AS rank, id, title, 'customer' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score 
    FROM customers,(SELECT @rank1:=0) AS t 
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) 
    ) 
    UNION DISTINCT 
    (

    SELECT @rank2:[email protected]+1 AS rank, id, title, 'project' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score 
    FROM projects,(SELECT @rank2:=0) AS t 
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) 
    ) 
    UNION DISTINCT 
    (

    SELECT @rank3:[email protected]+1 AS rank, id, title, 'task' AS type, MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) AS score 
    FROM tasks,(SELECT @rank3:=0) AS t 
    WHERE MATCH (title) AGAINST ('+test* ' IN BOOLEAN MODE) 
    ) 
) res 
ORDER BY rank 
LIMIT 6;