在此查询中获取数据计数的更好方法? [复制]

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 条件。

【讨论】:

以上是关于在此查询中获取数据计数的更好方法? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

是否有任何其他选项可以从表中获取总计数和同一查询中列的不同计数?

需要帮助编写查询以获取总计数和唯一计数

如何使用 sql 中的单个查询获取项目计数和总计数?

如何获取列中每个不同值的计数? [复制]

Django通过查询集中的唯一值获取总计数和计数

正确查询以获取 PostgreSQL 数据库中的当前连接数