使用不同的条件检索相同的列两次

时间:2016-05-17 20:10:09

标签: sql database postgresql

这个问题已经多次回答,但我无法让它发挥作用。我绑定使用this问题中的一些答案,但我总是“得到错误多于一个用作表达式的子查询返回的行”

我有以下sql查询:

SELECT DISTINCT p.name, pma.time AS  goal, pma.time AS assist 

FROM player p

INNER JOIN player_match pm
ON p.player_id = pm.player_id

INNER JOIN matches m
ON m.match_id = pm.match_id

INNER JOIN team_match tm
ON tm.team_id = p.team_id 

FULL JOIN player_match_activity pma
ON pma.player_id = p.player_id
AND pma.activity_id = '1'
AND pma.match_id = m.match_id

WHERE m.match_id = '163'
AND tm.home_away = 'home'

查询给出了以下结果:

 name    |    goal    |    assist
-------------------------------------
Ronaldo         1            1
Messi           3            3
Vardy  

列“辅助”显示与“目标”列相同的值。 线pma.activity_id ='1'选择目标。

如何设置列“辅助”使用完全相同的条件,例如“目标”列而不是pma.activity_id ='1'我想将其更改为“2”?

3 个答案:

答案 0 :(得分:1)

您可以向player_match_activity表添加其他联接,也可以将pma.activity_id = '1'更改为pma.activity_id IN ('1','2')并使用CASE表达式选择填充正确的列:

SELECT DISTINCT p.name, pma_goal.time AS  goal, pma_assist.time AS assist 
FROM player p
INNER JOIN player_match pm
   ON p.player_id = pm.player_id
INNER JOIN matches m
   ON m.match_id = pm.match_id
INNER JOIN team_match tm
   ON tm.team_id = p.team_id 
FULL JOIN player_match_activity pma_goal
   ON pma_goal.player_id = p.player_id
   AND pma_goal.activity_id = '1'
   AND pma_goal.match_id = m.match_id    
FULL JOIN player_match_activity pma_assist
   ON pma_assist.player_id = p.player_id
   AND pma_assist.activity_id = '2'
   AND pma_assist.match_id = m.match_id    
WHERE m.match_id = '163'
  AND tm.home_away = 'home'

可替换地:

SELECT p.name, MAX(CASE WHEN pma.activity_id = '1' THEN pma.time END) AS  goal
             , MAX(CASE WHEN pma.activity_id = '2' THEN pma.time END) AS  assist
FROM player p
INNER JOIN player_match pm
   ON p.player_id = pm.player_id
INNER JOIN matches m
   ON m.match_id = pm.match_id
INNER JOIN team_match tm
   ON tm.team_id = p.team_id 
FULL JOIN player_match_activity pma
   ON pma.player_id = p.player_id
   AND pma.activity_id IN ('1','2')
   AND pma.match_id = m.match_id    
WHERE m.match_id = '163'
  AND tm.home_away = 'home'
GROUP BY p.name

此外,不确定您是否需要在此使用FULL JOIN

答案 1 :(得分:1)

创建此查询的方式,最简单的方法是加入player_match_activity表两次:

SELECT DISTINCT p.name, pma_goal.time AS goal, pma_assist.time AS assist
FROM player p JOIN player_match pm ON p.player_id = pm.player_id
JOIN matches m ON m.match_id = pm.match_id
JOIN team_match tm ON tm.team_id = p.team_id
LEFT JOIN player_match_activity pma_goal ON pma_goal.player_id = p.player_id AND pma_goal.activity_id = '1' AND pma_goal.match_id = m.match_id
LEFT JOIN player_match_activity pma_assist ON pma_assist.player_id = p.player_id AND pma_assist.activity_id = 2 AND pma_assist.match_id = m.match_id
WHERE m.match_id = '163' AND tm.home_away = 'home';

这可能不是执行此SELECT的最佳方法,但这是我的最小更改建议。 ;)

答案 2 :(得分:1)

您尝试做的事情基本上称为PIVOT。 T-SQL有一个PIVOT关键字,但我不确定你是否使用T-SQL,所以这里是一个非T-SQL版本:

SELECT DISTINCT p.name, 
    SUM(CASE WHEN pma.activity_id = 1 THEN pma.time ELSE 0 END) AS goal, 
    SUM(CASE WHEN pma.activity_id = 2 THEN pma.time ELSE 0 END) AS assist
FROM player p
INNER JOIN player_match pm 
    ON p.player_id = pm.player_id
INNER JOIN team_match tm
    ON tm.team_id = p.team_id AND tm.match_id = pm.match_id
INNER JOIN player_match_activity pma
    ON pma.player_id = p.player_id
    AND pma.activity_id IN ('1', '2')
    AND pma.match_id = pm.match_id
WHERE pm.match_id = '163'
    AND tm.home_away = 'home'
GROUP BY p.name

我拿出了火柴桌,因为你似乎没有使用任何东西。但我也假设team_match中有一个match_id字段来弥补它。如果您想从查询中返回更多统计信息,则可以向SELECTpm.activity_id IN ('1', '2')添加新条目。