I have the following table (that I can't change)
id | name | date | available |
---|---|---|---|
1 | Book_1 | 2019-10-11 | Y |
2 | Book_1 | 2019-10-12 | Y |
3 | Book_1 | 2019-10-13 | Y |
4 | Book_1 | 2019-10-14 | Y |
5 | Book_2 | 2019-10-11 | Y |
6 | Book_2 | 2019-10-12 | Y |
7 | Book_2 | 2019-10-13 | Y |
8 | Book_3 | 2019-10-11 | Y |
9 | Book_3 | 2019-10-12 | N |
10 | Book_3 | 2019-10-13 | Y |
User wants to search for books that he/she can borrow from 2019-10-11 to 2019-10-13, and I need to return the following table
id | name | date | available |
---|---|---|---|
1 | Book_1 | 2019-10-11 | Y |
2 | Book_1 | 2019-10-12 | Y |
3 | Book_1 | 2019-10-13 | Y |
5 | Book_2 | 2019-10-11 | Y |
6 | Book_2 | 2019-10-12 | Y |
7 | Book_2 | 2019-10-13 | Y |
Notice that Book_3 is unavailable on 2019-10-12 so I cant' return it. Is possible with SQL?
CodePudding user response:
You can use a subquery with BOOL_AND
to check that available
is true
for all date
s for a book:
SELECT *
FROM books
WHERE date BETWEEN '2019-10-11' AND '2019-10-13'
AND name IN (
SELECT name
FROM books
WHERE date BETWEEN '2019-10-11' AND '2019-10-13'
GROUP BY name
HAVING BOOL_AND(available) -- or BOOL_AND(available = 'Y') if the column is not a BOOLEAN
);
id | name | date | available |
---|---|---|---|
1 | Book_1 | 2019-10-11T00:00:00.000Z | true |
2 | Book_1 | 2019-10-12T00:00:00.000Z | true |
3 | Book_1 | 2019-10-13T00:00:00.000Z | true |
5 | Book_2 | 2019-10-11T00:00:00.000Z | true |
6 | Book_2 | 2019-10-12T00:00:00.000Z | true |
7 | Book_2 | 2019-10-13T00:00:00.000Z | true |
CodePudding user response:
You can try to use the aggregate window function in subquery
SELECT *
FROM (
SELECT *,
MAX(CASE WHEN available = 'N' THEN 1 END)
OVER(PARTITION BY name) is_available
FROM T
) t1
WHERE is_available IS NULL AND
date BETWEEN '2019-10-11' AND '2019-10-13'