如何选择id只包含特殊值?

时间:2016-03-17 08:37:24

标签: sql oracle oracle-sqldeveloper having

我需要有关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。

有什么想法吗?

3 个答案:

答案 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;

最后的评论:

  • 我离开的时间是在2014-01-01' 2014-01-01'和#2016; 2016-01-01',因为我认为如果与你的例子无关,我认为这也与其他要求相关
  • 我离开了HUNT COUNT(ID)> 1,因为我认为这与其他要求有关,如果与您的示例无关

问候

相关问题