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

时间:2018-07-06 19:12:42

标签: mysql sql select foreign-keys union

我有一个图书馆(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个查询似乎效率很低。

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

如果您只想要总数为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
)

答案 2 :(得分:1)

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的替代方法,具有类似的结果。但我会同意他的。与他不同的是,在这本书中,符合多个条件的一本书将只包括在第一个条件的计数中。

但是,如果book_loans表非常大,则您仍可以考虑在WHERE子句中包含OR条件。