2016-11-17 3 views
1

Ich hoffe, es gibt eine einfache Antwort darauf. Die Teilnehmer fahren über eine Serie von 3 Rennen. Einige Konkurrenten tauchen nur für ein Rennen auf. Wie könnte ich ein Endergebnis für ALLE Konkurrenten zeigen?Wählen Sie aus Tabellen mit verschiedenen Anzahlen von Zeilen

Rennen 1

+------+--------+ 
| name | result | 
+------+--------+ 
| Ali |  30 | 
| Bob |  28 | 
| Cal |  26 | 
+------+--------+ 

Rennen 2

+------+--------+ 
| name | result | 
+------+--------+ 
| Ali |  32 | 
| Bob |  31 | 
| Dan |  24 | 
+------+--------+ 

Rennen 3

+------+--------+ 
| name | result | 
+------+--------+ 
| Eva |  23 | 
| Dan |  25 | 
+------+--------+ 

Das Endergebnis sollte wie folgt aussehen:

+------+--------+--------+--------+ 
| name | result | result | result | 
+------+--------+--------+--------+ 
| Ali |  30 |  32 |  | 
| Bob |  28 |  31 |  | 
| Cal |  26 |  |  | 
| Dan |  |  24 |  25 | 
| Eva |  |  |  23 | 
+------+--------+--------+--------+ 

Das Problem, das ich habe, ist mit der Bestellung nach Namen aus mehreren Tabellen.

Hier ist die Beispieldaten:

CREATE TABLE race (name varchar(20), result int); 
CREATE TABLE race1 LIKE race; 
INSERT INTO race1 VALUES ('Ali', '30'), ('Bob', '28'), ('Cal', '26'); 
CREATE TABLE race2 like race; 
insert INTO race2 VALUES ('Ali', '32'), ('Bob', '31'), ('Dan', '24'); 
CREATE TABLE race3 LIKE race; 
INSERT INTO race3 VALUES ('Eva', '23'), ('Dan', '25'); 

Vielen Dank!

+0

Ich würde empfehlen, alle Rennen in 1 Tisch. 'CREATE TABLE rennen (Name varchar (20), race_id, Ergebnis int);' Dies sollte es viel einfacher zu Abfrage machen. Vor allem, wenn Sie später weitere Rennen hinzufügen möchten. –

+0

Ich habe das versucht, konnte aber keine Abfrage erstellen, die keinen Pivot enthielt, um die mehreren Zeilen pro Name in das richtige Ausgabeformat zu bringen. Hast du einen Vorschlag? – logicmonkey

+0

Ich habe eine neue Antwort erstellt. –

Antwort

5

Hier gehen wir !!!

select race1.name as name, race1.result, race2.result, race3.result from race1 
    left join race2 on race2.name = race1.name 
    left join race3 on race3.name = race1.name 

union 

select race2.name as name, race1.result, race2.result, race3.result from race2 
    left join race1 on race1.name = race2.name 
    left join race3 on race3.name = race2.name 

union 

select race3.name as name, race1.result, race2.result, race3.result from race3 
    left join race1 on race1.name = race3.name 
    left join race2 on race2.name = race3.name; 

Es funktioniert :)

+0

Das Ziehen der separaten Namensspalten zusammen mit AS ist genau der Trick, den ich brauchte. Ich dachte, sie wären nur Aliase, aber das zeigt, dass AS deutlich funktionaler ist. Vielen Dank! – logicmonkey

0
select s.name, 
     max(case when s.R = 'Result1' then s.result else '' end) as result1, 
     max(case when s.R = 'Result2' then s.result else '' end) as result2, 
     max(case when s.R = 'Result3' then s.result else '' end) as result3 
from 
(
select 'Result1' as R,r1.* from race1 r1 
union all 
select 'Result2' as R,r2.* from race2 r2 
union all 
select 'Result3' as R,r3.* from race3 r3 
) s 
group by s.name 

Ergebnis

+------+---------+---------+---------+ 
| name | result1 | result2 | result3 | 
+------+---------+---------+---------+ 
| Ali | 30  | 32  |   | 
| Bob | 28  | 31  |   | 
| Cal | 26  |   |   | 
| Dan |   | 24  | 25  | 
| Eva |   |   | 23  | 
+------+---------+---------+---------+ 
5 rows in set (0.00 sec) 
+0

es scheint wie ** Race1 **, ** Race2 ** und ** Race3 ** sind drei verschiedene Tabellen. – Viki888

+0

@ viki888 Ihr Punkt ist? –

0

Ich persönlich würde das Schema in einer anderen Art und Weise erstellen. Eine Tabelle für die Benutzer, eine für die Rennen und eine, die beide verbindet:

-- Create syntax for TABLE 'races' 
CREATE TABLE `races` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) DEFAULT NULL, 
    `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

-- Create syntax for TABLE 'users' 
CREATE TABLE `users` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) DEFAULT NULL, 
    `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

-- Create syntax for TABLE 'race_results' 
CREATE TABLE `race_results` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `race_id` int(11) NOT NULL, 
    `user_id` int(11) NOT NULL, 
    `result` int(11) NOT NULL, 
    `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

Lassen Sie uns einige Daten einfügen (sollten Sie mit Ihrem Datensatz gleich sein).

-- Insert data 
INSERT INTO users (name)values('Ali'),('Bob'),('Cal'),('Dan'), ('Eva'); 
INSERT INTO races (name)values('Race1'),('Race2'),('Race3'); 
INSERT INTO race_results (user_id, race_id, result)values(1,1,30),(2,1,30),(1,2,28),(2,2,31),(3,1,26),(4,2,24),(4,3,25),(5,3,23); 

Dann könnten Sie die Abfrage wie folgt schreiben:

-- Static version 
SELECT us.name, sum(if(ra.name='Race1', result, null)) as Race1, sum(if(ra.name='Race2', result, null)) as Race2, sum(if(ra.name='Race3', result, null)) as Race3 
FROM race_results as rr 
LEFT JOIN users as us on us.id = rr.user_id 
LEFT JOIN races as ra on ra.id = rr.race_id 
GROUP BY us.id; 

dem Sie das Ergebnis Sie suchen gibt. (Ich habe die Spaltennamen geändert, um deutlicher zu machen, welches Ergebnis zu welchem ​​Rennen gehört.)

Aber ich muss zugeben, dass das für 3 Rennen funktioniert, aber was ist wenn du 30 oder mehr hast? Hier

ist eine dynamischere Version der obigen Abfrage, die Art selbst erzeugt;)

-- Dynamic version 
SET @sql = ''; 
SELECT 
    @sql := CONCAT(@sql,if(@sql='','',', '),temp.output) 
FROM 
    (SELECT 
     CONCAT("sum(if(ra.name='", race.name, "', result, null)) as ", race.name) as output 
    FROM races as race 
) as temp; 

SET @sql = CONCAT("SELECT us.name,", @sql, " FROM race_results as rr LEFT JOIN users as us on us.id = rr.user_id LEFT JOIN races as ra on ra.id = rr.race_id GROUP BY 1;"); 
SELECT @sql; 
PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 
Verwandte Themen