在此查询中获取数据计数的更好方法? [复制]
Posted
技术标签:
【中文标题】在此查询中获取数据计数的更好方法? [复制]【英文标题】:Better way to get counts of data in this query? [duplicate] 【发布时间】:2018-07-06 19:12:41 【问题描述】:我有一个图书馆 (books
) 和另一个桌子,每次有人借书或带回一本书时,它都会被记录下来 (book_loans
)。
基本上我想查看在某个时间签出的所有书籍,有多少:
属于“奇幻”类型 超过 500 页 是精装书我想一次完成所有这些,我现在使用 4 个查询,有没有更好的方法?
PS:book_loans
.bookID 是books
.id 的外键:
SELECT * FROM
(
SELECT COUNT(*) FROM `books` AS bks
INNER JOIN `book_loans` AS bs ON bks.id = bs.bookID
WHERE bs.time = '2017-07-01 02:16:00' AND bs.signedout = 1 AND bks.genre = 'fantasy'
UNION
SELECT COUNT(*) FROM `books` AS bks
INNER JOIN `book_loans` AS bs ON bks.id = bs.bookID
WHERE bs.time = '2017-07-01 02:16:00' AND bs.signedout = 1 AND bks.pages > 500
UNION
SELECT COUNT(*) FROM `books` AS bks
INNER JOIN `book_loans` AS bs ON bks.id = bs.bookID
WHERE bs.time = '2017-07-01 02:16:00' AND bs.signedout = 1 AND bks.hardcover = 1
) x;
为此总共执行 4 个查询似乎效率很低。
【问题讨论】:
【参考方案1】:SELECT SUM(bks.genre = 'fantasy') as fantasy,
SUM(bks.pages > 500) as pages,
SUM(bks.hardcover = 1) as hardcover
FROM `books` AS bks
INNER JOIN `book_loans` AS bs ON bks.id = bs.bookID
WHERE bs.time = '2017-07-01 02:16:00' AND bs.signedout = 1
【讨论】:
非常感谢!【参考方案2】:如果您只想要全部 3 个的总数,或者,如果您需要 3 个不同的总数,每个总数一个,或者您需要不同的东西,这应该可以满足您的需要。
SELECT COUNT(*) FROM `books` AS bks
INNER JOIN `book_loans` AS bs ON bks.id = bs.bookID
WHERE bs.time = '2017-07-01 02:16:00' AND bs.signedout = 1
AND (
bks.genre = 'fantasy'
OR bks.pages > 500
OR bks.hardcover = 1
)
【讨论】:
【参考方案3】:SELECT CASE WHEN bks.genre = 'fantasy' THEN 'genre match'
WHEN bks.pages > 500 THEN 'page count met'
WHEN bks.hardcover = 1 THEN 'is hardcover'
END AS condition
, COUNT(*)
FROM `books` AS bks
INNER JOIN `book_loans` AS bs ON bks.id = bs.bookID
WHERE bs.time = '2017-07-01 02:16:00' AND bs.signedout = 1
AND (bks.genre = 'fantasy' OR bks.pages > 500 OR bks.hardcover = 1)
GROUP BY condition;
这是 juergen d's 的替代方法,具有相似的结果;但我会先和他一起去。与他不同的是,在这本书中,匹配多个条件的书只会包含在第一个条件的计数中。
但是,如果 book_loans 表非常大,您仍可以考虑在 WHERE 子句中包含 OR 条件。
【讨论】:
以上是关于在此查询中获取数据计数的更好方法? [复制]的主要内容,如果未能解决你的问题,请参考以下文章