2016-11-17 9 views
1

간단한 답이 있기를 바랍니다. 경쟁자는 일련의 3 개 종족을 통해 경쟁합니다. 일부 경쟁자는 한 경주에만 나타납니다. 모든 경쟁자에게 어떻게 최종 결과를 보여줄 수 있습니까?행 수가 다른 표에서 선택하십시오.

레이스 1

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

인종이

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

내가 한 테이블에서 모든 인종을 두는 것을 권 해드립니다. '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; 

은 (데이터 세트 같아야한다)의 일부 데이터를 삽입하자.

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

당신에게 당신이 찾고있는 결과를 제공합니다

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

그럼 당신은 이런 식으로 쿼리를 작성할 수 있습니다. (어떤 결과가 어떤 레이스에 속하는지 명확하게하기 위해 열 이름을 변경했습니다.)

그러나 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; 
관련 문제