我有一个图书馆(books
)和另一个桌子,每当有人借书或带回书本时,它都会被记录下来(book_loans
)。
基本上,我想查看在某个特定时间退出的所有图书中有多少:
我想一次完成所有操作,现在正在使用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个查询似乎效率很低。
答案 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条件。