我有两张桌子,系列和卡片(一对多:每个系列都有很多卡片)
series: seriesID, seriesName...
cards: cardID, seriesID, cardActive (bit), cardUsed(bit)
我想返回一个查询:
目标是拥有一个包含以下标题的表格:
seriesID | seriesName | total cards count | inactive cards | etc..
我尝试过使用它:
SELECT seriesID,COUNT(*) AS cardsCount FROM cards GROUP BY seriesID
但我想知道是否需要5个不同的查询来获取指定的统计信息。 我应该使用功能吗?
答案 0 :(得分:1)
你可以对位字段求和(除非它产生奇偶校验值而不是INTEGER),CASE表达式有助于最后一位:
SELECT s.SeriesID,
s.SeriesName,
COUNT(*) AS "Total Cards",
SUM(NOT c.CardActive) AS "Inactive Cards",
SUM(NOT c.CardUsed) AS "Unused Cards",
SUM(CASE WHEN c.CardActive AND NOT c.CardUsed THEN 1 ELSE 0 END)
AS "Active and Unused"
FROM Series AS s
JOIN Cards AS c ON s.SeriesID = c.SeriesID
GROUP BY s.SeriesID, s.SeriesName;
鉴于它是MySQL,你可以省略GROUP BY中的s.SeriesName
,你可能会得到相同的答案;大多数其他DBMS都会要求GROUP BY子句中的非聚合列。
SUM(NOT c.CardActive)
和SUMN(NOT c.CardUsed)
表达式可能无法满足我的要求。在那种情况下:
SUM(CASE WHEN c.CardActive THEN 0 ELSE 1 END) AS "Inactive Cards",
SUM(CASE WHEN c.CardUsed THEN 0 ELSE 1 END) AS "Unused Cards",
会做到这一点。
对于至少列出一张卡片的系列来说,这一切都很干净。如果你的系列中没有卡而你想在输出中使用它们,那么你需要在表之间进行LEFT OUTER JOIN,你必须担心空值。这一次,整个过程都需要SUM(CASE...END)
。请注意,COUNT(C.CardID)
仅计算非空值,因此当系列没有卡时,这将为零。
SELECT s.SeriesID,
s.SeriesName,
COUNT(c.CardID) AS "Total Cards",
SUM(CASE WHEN c.CardID IS NULL THEN 0 WHEN c.CardActive THEN 0 ELSE 1 END)
AS "Inactive Cards",
SUM(CASE WHEN c.CardID IS NULL THEN 0 WHEN c.CardUsed THEN 0 ELSE 1 END)
AS "Unused Cards",
SUM(CASE WHEN c.CardID IS NULL THEN 0
WHEN c.CardActive AND NOT c.CardUsed THEN 1 ELSE 0
END) AS "Active and Unused"
FROM Series AS s
LEFT JOIN Cards AS c ON s.SeriesID = c.SeriesID
GROUP BY s.SeriesID, s.SeriesName;