您可能可以对位字段求和(除非产生奇偶校验值而不是整数),并且 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,您可以s.SeriesName
从 GROUP BY 中省略,您可能会得到相同的答案;大多数其他 DBMS 将要求 GROUP BY 子句中的两个非聚合列。
有可能SUM(NOT c.CardActive)
andSUMN(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;