Having issues combining HAVING with WHERE on a very simple QUERY

微笑、不失礼 提交于 2021-02-08 12:01:20

问题


This is what I have tried so far:

SELECT group_id, player_id as winner_id
/* 
,sum(M1.first_score + M2.second_score), sum(M2.first_score + M1.second_score)
*/

FROM players as P1

LEFT JOIN matches as M1 
ON M1.first_player = P1.player_id

LEFT JOIN matches as M2
ON M2.second_player = P1.player_id

LEFT JOIN matches as M3
ON M3.first_player = P1.player_id

LEFT JOIN matches as M4
ON M4.second_player = P1.player_id


--WHERE P1.player_id is not null /*or P2.player_id is not null*/

GROUP BY group_id, P1.player_id

/*
HAVING 
sum(M1.first_score + M2.second_score) > sum(M2.first_score + M1.second_score)
OR
sum(M3.first_score + M4.second_score) > sum(M4.first_score + M3.second_score)
*/

ORDER BY group_id ASC, player_id ASC

The results that I am getting are:

1,30
1,45
1,65
2,20
2,50
3,40

I know I am missing something very obvious as usual

This is my most recent

attempt

-- write your code in PostgreSQL 9.4
SELECT 
group_id,  player_id as winner_id

/* 
,sum(M1.first_score + M2.second_score), sum(M2.first_score + M1.second_score)
*/

FROM players as P1

LEFT JOIN matches as M1 
ON M1.first_player = P1.player_id

LEFT JOIN matches as M2
ON M2.second_player = P1.player_id

LEFT JOIN matches as M3
ON M3.first_player = P1.player_id

LEFT JOIN matches as M4
ON M4.second_player = P1.player_id


GROUP BY group_id, P1.player_id, M1,M2,M3,M4

/*
HAVING 
(M1 is not null) OR (M2 is not null) OR (M3 is not null) OR (M4 is not null)
*/

/*
HAVING 
sum(M1.first_score + M2.second_score) > sum(M2.first_score + M1.second_score)
OR
sum(M3.first_score + M4.second_score) > sum(M4.first_score + M3.second_score)
*/

ORDER BY group_id ASC
/*, player_id DESC
*/

How can I fix the query so that I can get the expected results


回答1:


I don't have any PostgreSQL background but lets see if this works:

I would start this by simplifying it, by writing a query that first returns the total score by player:

SELECT player_id, SUM(score) score
FROM (
  SELECT first_player as player_id, first_score as score
  FROM matches
  UNION ALL
  SELECT second_player, second_score
  FROM matches
)
GROUP BY player_id

Now, join that dataset to players to find the groups:

SELECT w.player_id, p.group_id, w.score
FROM
(
  SELECT player_id, SUM(score) score
  FROM (
    SELECT first_player as player_id, first_score as score
    FROM matches
    UNION ALL
    SELECT second_player, second_score
    FROM matches
  )
  GROUP BY player_id
) as w
inner join players p
on p.player_id = w.player_id

Now we have all players, their total score and their group. We want to identify the winner by group? We can use ranking functions to do this:

SELECT 
w.player_id, 
p.group_id, 
w.score, 
RANK() OVER (PARTITION BY p.group_id ORDER BY score DESC) as group_placement
FROM
(
  SELECT player_id, SUM(score) score
  FROM (
    SELECT first_player as player_id, first_score as score
    FROM matches
    UNION ALL
    SELECT second_player, second_score
    FROM matches
  )
  GROUP BY player_id
) as w
inner join players p
on p.player_id = w.player_id

Now we just pick out the top ones in each group (rank = 1) using WHERE

  SELECT 
  player_id, 
  group_id
  FROM
  (
      SELECT 
      w.player_id, 
      p.group_id, 
      w.score, 
      RANK() OVER (PARTITION BY p.group_id ORDER BY score DESC) as group_placement
      FROM
      (
        SELECT player_id, SUM(score) score
        FROM (
          SELECT first_player as player_id, first_score as score
          FROM matches
          UNION ALL
          SELECT second_player, second_score
          FROM matches
        )
        GROUP BY player_id
      ) as w
      inner join players p
      on p.player_id = w.player_id
    ) as gp
    WHERE group_placement = 1

Looks complicated? yes, but you can see have the final result is provided bit by bit. Each step of this is a 'subtable' and you can run and observe the data at each point.



来源:https://stackoverflow.com/questions/51487670/having-issues-combining-having-with-where-on-a-very-simple-query

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!