2016-11-17 65 views
1

我希望對此有一個簡單的答案。選手參加一系列3場比賽。有些競爭對手只參加一場比賽。我怎麼能展示所有競爭對手的最終結果?從具有不同行數的表中選擇

比賽1

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

比賽2

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

比賽3

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

最後的結果應該是這樣的:

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

我遇到的問題是從多個表中按名稱排序。

下面是示例數據:

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'); 

非常感謝!

+0

我建議把所有的比賽中1臺。 'CREATE TABLE race(name varchar(20),race_id,result int);' 這應該使查詢更容易。特別是如果你想在以後增加更多的比賽。 –

+0

我試過,但不能拿出一個查詢,沒有涉及到一個數據透視表,以獲得每個名稱的多個行到正確的輸出格式。你有什麼建議嗎? – logicmonkey

+0

我創建了一個新的答案。 –

回答

5

在這裏,我們走!

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; 

據工作:)

+0

將單獨的名稱列與AS一起拉出正是我需要的技巧。我認爲他們只是別名,但這表明AS顯然比這更有用。謝謝! – 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 

結果

+------+---------+---------+---------+ 
| 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

看起來好像** Race1 **,** Race2 **和** Race3 **是三張不同的表格。 – Viki888

+0

@ viki888你的觀點是? –

0

我個人將創建以不同的方式架構。 一表的用戶,一個用於比賽和一個連接兩個:

-- 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; 

讓我們插入一些數據(應等於你的數據集)。

-- 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); 

然後,你可以這樣寫查詢:

-- 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; 

它給你,你正在尋找的結果。 (我改變了列名,使其更明顯哪個結果屬於哪一場比賽。)

但我必須承認,這對3場比賽可行,但如果你有30或更多?

這裏是上面的查詢,哪一種創造本身的一個更有活力的版本;)

-- 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;