我需要有关sql查询的帮助。我有一张这样的桌子:
ID bookType Date
----------- ---------- ------
1 85 01.01.2014
1 86 01.01.2014
1 88 01.01.2014
1 3005 01.01.2014
1 3028 01.01.2014
2 74 01.01.2016
2 85 01.01.2016
2 86 01.01.2016
3 88 01.01.2015
3 3005 01.01.2015
我需要一个查询,它只返回所有带有booktype 85,86的id和带有书籍类型88,3005,3028的NOT id' s。所有其他类型都不相关,可以包括在内。
示例:
我只想要ID 2,因为没有88,3005,3028的书籍类型。它的ID为74,但这并不重要,可以包含它。
我试过这样的事情:
SELECT bookid AS id, COUNT(bookid) AS number
FROM books
WHERE date BETWEEN '01.01.2014' and '01.01.2016'
and booktype in (85,86)
GROUP BY bookid
HAVING COUNT(bookid) >1
MINUS
SELECT bookid AS id, count(bookid) AS number
FROM books
WHERE date BETWEEN '01.01.2014' and '01.01.2016'
and booktype in (88,3005,3028)
GROUP BY bookid;
它不起作用。我每次都得到booktype 88或其他包含的结果。
我试过EXCEPT
,但Oracle SQL Developer并不知道ist。
有什么想法吗?
答案 0 :(得分:4)
试试这个:
SELECT bookid AS id, COUNT(*) AS number
FROM books
WHERE date BETWEEN DATE '2014-01-01' and DATE '2016-01-01'
GROUP BY bookid
HAVING COUNT(DISTINCT CASE WHEN booktype IN (85,86) THEN booktype END) = 2 AND
COUNT(CASE WHEN booktype IN (88, 3005, 3028) THEN 1 END) = 0
如果您只想计算(85,86)
次出现次数,请使用:
COUNT(CASE WHEN booktype IN (85,86) THEN 1 END)
而不是:
COUNT(*)
答案 1 :(得分:0)
试试这个:
select id,booktype,daata,
count(*) over (partition by id) count
from tmp;
tmp之后;你可以把id = 2或者你想要的东西放在哪里:)
答案 2 :(得分:0)
我发现您的SQL和列名称之间存在一些不一致。
表格中没有bookid,你错过了booktype ......
假设您的第一个查询是:
SELECT ID AS ID, COUNT(ID) AS number FROM books WHERE date
BETWEEN '2014-01-01' and '2016-01-01' and bookType in (85,86)
GROUP BY ID
HAVING COUNT(ID) >1;
这将有结果集:
ID number
1 2
2 2
您的第二个查询
SELECT ID AS ID, COUNT(ID) AS number FROM books WHERE date
BETWEEN '2014-01-01' and '2016-01-01' and bookType in (88, 3005, 3028)
GROUP BY ID;
这将有结果集:
ID number
1 3
3 2
ORACLE中的MINUS运算符仅返回第一个查询返回的唯一行,但不返回第二个查询返回的唯一行。因此,整个查询将返回第一个记录集,因为第一个查询的结果都与第二个查询的结果不同。
如果您在查询中删除count语句,您将拥有:
第一次查询
SELECT ID AS ID FROM books WHERE date
BETWEEN '2014-01-01' and '2016-01-01' and bookType in (85,86)
GROUP BY ID
HAVING COUNT(ID) >1;
结果集
ID
1
2
第二次查询:
SELECT ID AS ID FROM books WHERE date
BETWEEN '2014-01-01' and '2016-01-01' and bookType in (88, 3005, 3028)
GROUP BY ID;
结果集
ID
1
3
并应用MINUS运算符,您将根据需要获得2,因为1位于第二个结果集中。
这只是为了确认您的逻辑是正确的,但没有完全考虑到MINUS对结果集的操作方式。
所以你的查询必须是:
SELECT ID AS ID FROM books WHERE date
BETWEEN '2014-01-01' and '2016-01-01' and bookType in (85,86)
GROUP BY ID
HAVING COUNT(ID) >1
MINUS
SELECT ID AS ID FROM books WHERE date
BETWEEN '2014-01-01' and '2016-01-01' and bookType in (88, 3005, 3028)
GROUP BY ID;
最后的评论:
问候