oracle 如何在COUNT()聚合中包含零?

63lcw9qa  于 2022-11-03  发布在  Oracle
关注(0)|答案(4)|浏览(238)

我有三个表,我把它们连接起来,并使用where Group by - count,我无法得到输出中结果为零的国家。我仍然迷路了。
下面是SQLfiddle
http://sqlfiddle.com/#!4/e330ec/7
电流输出

(UKD)   3
(EUR)   2
(USA)   2
(CHE)   1

预期输出

(UKD)   3
(EUR)   2
(IND)   0
(LAO)   0
(USA)   2
(CHE)   1
szqfcxe2

szqfcxe21#

您可以按照另一个答案中的建议使用RIGHT JOIN,也可以对连接进行重新排序并使用LEFT JOIN

SELECT
  C.COUNTRY_CODE,
  COUNT(GAME_TYPE)
FROM
  COUNTRY_TABLE C
  LEFT JOIN PLAYER_TABLE P ON P.COUNTRY_ID = C.COUNTRY_ID
  LEFT JOIN PLAYER_GAME_TYPE G ON P.PLAYER_ID = G.PLAYER_ID
WHERE
  G.GAME_TYPE = 'GOLF'
  OR G.GAME_TYPE IS NULL
GROUP BY
  C.COUNTRY_CODE;

请注意WHERE子句中包含了OR G.GAME_TYPE IS NULL--如果只有G.GAME_TYPE = 'GOLF',则所需的结果将在连接 * 之后被过滤掉 *。

vddsk6oq

vddsk6oq2#

您可以选择应用以下步骤:

  • 将第二个LEFT JOIN转换为RIGHT JOIN(因为所需的缺失缩写位于右侧的COUNTRY_TABLE中)
  • 通过在ON子句之后取,使筛选条件(后跟WHERE子句)G.GAME_TYPE = 'GOLF'成为匹配条件

例如:

SELECT C.COUNTRY_CODE, COUNT(GAME_TYPE)
  FROM PLAYER_TABLE P
  LEFT JOIN PLAYER_GAME_TYPE G
    ON P.PLAYER_ID = G.PLAYER_ID
  RIGHT JOIN COUNTRY_TABLE C
    ON P.COUNTRY_ID = C.COUNTRY_ID
   AND G.GAME_TYPE = 'GOLF'
 GROUP BY C.COUNTRY_CODE;

Demo

cgyqldqp

cgyqldqp3#

简单地改变表的连接顺序就可以解决这个问题

SELECT C.COUNTRY_CODE, COUNT(GAME_TYPE)
FROM COUNTRY_TABLE C -- get all countries
LEFT JOIN PLAYER_TABLE P ON P.COUNTRY_ID = C.COUNTRY_ID -- join all players
LEFT JOIN PLAYER_GAME_TYPE G ON P.PLAYER_ID = G.PLAYER_ID AND G.GAME_TYPE = 'GOLF' -- join only GOLF games
GROUP BY C.COUNTRY_CODE;

sqlize online

6ioyuze2

6ioyuze24#

这是您的查询:

SELECT C.COUNTRY_CODE, COUNT(GAME_TYPE)
FROM PLAYER_TABLE P 
LEFT JOIN PLAYER_GAME_TYPE G ON P.PLAYER_ID = G.PLAYER_ID
LEFT JOIN COUNTRY_TABLE C ON P.COUNTRY_ID = C.COUNTRY_ID
WHERE G.GAME_TYPE = 'GOLF'
GROUP BY C.COUNTRY_CODE;

这个查询似乎试图选择所有球员,即使他们不是高尔夫球手。但是,这是行不通的,因为WHERE G.GAME_TYPE = 'GOLF'删除了所有外部联接行,所以最终得到了一个内部联接(所有打高尔夫球的球员)。最后,您外部联接了国家表,这将为您提供不属于某个国家的球员。这是缩进的吗?我不这么认为。
你想要的是国家,所以从国家中选择。然后适当地外部加入玩家和类型,以便计数。

SELECT c.country_code, COUNT(g.game_type) as golfers_in_country
FROM country_table c
LEFT JOIN player_table p ON p.country_id = c.country_id
LEFT JOIN player_game_type g ON g.player_id = p.player_id AND g.game_type = 'GOLF'
GROUP BY c.country_code
ORDER BY c.country_code;

你可以使用CTE来提高可读性。它比较长,但是意图非常清晰。这样构造一个查询有助于避免错误。

WITH golfers AS
(
  SELECT *
  FROM player_table
  WHERE player_id IN
  (
    SELECT player_id
    FROM player_game_type
    WHERE game_type = 'GOLF'
  )
)
SELECT c.country_code, COUNT(g.player_id) as golfers_in_country
FROM country_table c
LEFT JOIN golfers g ON g.country_id = c.country_id
GROUP BY c.country_code
ORDER BY c.country_code;

相关问题