返回未在数据库中两次列出的项目

时间:2019-09-18 10:41:10

标签: sql-server tsql

利用以下数据,我如何仅识别在taskid中没有1 AND 2项的行状态栏? (第7/8行)

CREATE TABLE TestTable
        ([id] bigint, [taskid] uniqueidentifier, [status] int)
    ;

    INSERT INTO TestTable
        ([id], [taskid], [status])
    VALUES
        (1, '7AF6F773-7B55-4B51-9742-00C829641C8D', 1),
        (2, '7AF6F773-7B55-4B51-9742-00C829641C8D', 2),
        (3, '21DA1039-9EA1-42BE-A2BC-02AC46D6A34B', 1),
        (4, '21DA1039-9EA1-42BE-A2BC-02AC46D6A34B', 2),
        (5, '5FC0BCEA-A097-466B-A1F8-120A57584406', 1),
        (6, '5FC0BCEA-A097-466B-A1F8-120A57584406', 2),
        (7, '14227447-E42F-41A1-8431-1C6465814455', 1),
        (8, '66383B5F-3795-4E4B-85C9-223EA5B3D007', 2)
    ;

我已经尝试过该查询,但是它返回所有行

select [id],[taskid], [status] 
from testtable
group by status, taskid, id
  having count(taskid) < 2
 order by taskid 

不知道该如何处理?子查询/ CTE是否适用?如果是这样,那将如何工作?我认为这很容易实现。

我的预期输出是

7, '14227447-E42F-41A1-8431-1C6465814455', 1
8, '66383B5F-3795-4E4B-85C9-223EA5B3D007', 2

我希望返回这些行,因为它们是仅有的两个没有1和2条目的行。因此count中的taskId应该是1。

SQL Fiddle链接:http://sqlfiddle.com/#!18/4acb9/2

3 个答案:

答案 0 :(得分:2)

使用COUNT作为分析函数的一种方法:

WITH cte AS (
    SELECT *, COUNT(*) OVER (PARTITION BY taskid) cnt
    FROM testtable
)

SELECT id, taskid, status
FROM cte
WHERE cnt = 1

这里的想法是首先遍历表并为属于同一taskid的每组记录生成一个计数。然后,子查询该CTE并将其限制为仅出现一次的任务。

答案 1 :(得分:2)

我已经通过不重复行的子查询解决了该问题。

SELECT id, taskid, status
from testtable
where taskId IN (
 SELECT distinct taskid
 from TestTable
 group by taskid
 having count(taskid) < 2)

之所以这样做,是因为您只需要按taskid对其进行分组,并且如果没有其他查询或加入它就无法恢复它。

答案 2 :(得分:1)

尝试:

select * 
from TestTable 
where taskid not in (
                   select taskid 
                   from TestTable 
                   where status=1 and taskid in 
                                 (select taskid 
                                  from TestTable 
                                  where status=2))

这不是最佳解决方案,但可以为您