2016-12-30 156 views
2

我有一个简单的两列表。举例来说,我们可以使用以下来构建数据:在SQL中避免重复子查询的最佳方法

CREATE TABLE Duplicates 
    (assignmentid varchar(5), questionid varchar(5)); 

INSERT INTO Duplicates 
    (assignmentid, questionid) 
VALUES 
    ('aaaaa', '11111'), 
    ('aaaaa', '22222'), 
    ('bbbbb', '22222'), 
    ('bbbbb', '33333'), 
    ('bbbbb', '33333'); 

有两行是相同的。还有一个问题出现在多个作业上。后者是一个有效的场景,我试图获得所有作为多个作业一部分的问题的查询。所以我期望的输出是:

aaaaa, 22222 
    bbbbb, 22222 

我能得到这个结果与此:

SELECT main.questionid, sub.assignmentid 
FROM (
    SELECT questionid, count(assignmentid) AS AssignmentCount 
    FROM ( 
     SELECT DISTINCT questionid, assignmentid 
     FROM Duplicates 
    ) sub 
    GROUP BY questionid 
    HAVING AssignmentCount > 1 
) main 
INNER JOIN (
    SELECT DISTINCT questionid, assignmentid 
    FROM Duplicates 
) sub ON main.questionid = sub.questionid; 

正如你可以看到被重复两次的DISTINCT子查询。我可以通过使用WITH命令来避免这种情况,但我的理解是,这并不一定意味着子查询只会被执行一次。所以现在我在StackOverflow中,询问是否有人知道更有效的方式来运行此查询。

+0

CTE(“with”)query **将被执行一次。 –

+0

@a_horse_with_no_name请展开CTE评论。我认为应该将CTE视为一个视图(而不是临时表),这意味着每次使用视图时,都会对基础表重复调用。也许我误解了。这里是我提到的另一个stackoverflow页面的链接: Kumar

回答

0

可以简化到:

select * 
from duplicates 
where questionid in (select questionid 
        from duplicates 
        group by questionid 
        having count(distinct assignmentid) > 1); 

子查询返回被分配到一个以上的assignmentid所有questionids。

0

只需使用窗口功能。一种方法是答案的次数比较不同答案的计数:

select distinct answerid, questionid 
from (select d.*, 
      count(distinct answerid) over (partition by questionid) as cntd, 
      count(*) over (partition by questionid) as cnt 
     from duplicates d 
    ) d 
where cntd <> cnt; 

编辑:

你可以做到这一点没有count(distinct)但它需要一个额外的子查询:

select distinct answerid, questionid 
from (select d.*, 
      count((seqnum = 1)::int) over (partition by questionid) as cntd, 
      count(*) over (partition by questionid) as cnt 
     from (select d.*, 
        row_number() over (partition by questionid, answerid order by questionid) as seqnum 
      from duplicates d 
      ) d 
    ) d 
where cntd <> cnt; 

这使用行号进行不同的计算。

+0

不幸的是Postgres不支持窗口功能中的'distinct' –

+0

@a_horse_with_no_name。 。 。谢谢。我很方便地忘记了SQL Server不是唯一具有此缺陷的数据库。 –