如何 select 仅包含特殊值的 id?

How to select id's which contains just special values?

我需要有关 sql 查询的帮助。我有一个 table 这样的:

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

我需要一个查询,returns 只是所有 id 的书类型为 85、86 而不是 id 的书类型为 88,3005,3028。其他类型不相关,可以包含。

示例:

我只想要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 开发人员不知道。

试试这个:

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(*) 

试试这个:

  select id,booktype,daata,
    count(*) over (partition by id) count
    from tmp;

tmp 之后;你可以把 id=2 或任何你想要的地方:)

我发现您的 SQL 和列名称之间有些不一致。

table 中没有 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 运算符 return 仅由第一个查询而不是第二个查询编辑的唯一行 return。因此整个查询将 return 第一个记录集,因为第一个查询的两个结果与第二个查询的结果不同。

如果您在查询中删除计数语句,您将拥有:

第一次查询

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

并应用减号运算符,您将只得到所需的 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”和“2016-01-01”之间留下了 WHERE 日期,因为我认为它与其他要求相关,如果与您的示例无关
  • 我留下了 HAVING COUNT(ID) >1,因为我认为它与其他要求相关,如果与您的示例无关

此致