避免SQL中重复子查询的最佳方法
我有一个简单的两列表。例如,我们可以使用以下方法来构建数据:避免SQL中重复子查询的最佳方法,sql,postgresql,query-optimization,Sql,Postgresql,Query Optimization,我有一个简单的两列表。例如,我们可以使用以下方法来构建数据: CREATE TABLE Duplicates (assignmentid varchar(5), questionid varchar(5)); INSERT INTO Duplicates (assignmentid, questionid) VALUES ('aaaaa', '11111'), ('aaaaa', '22222'), ('bbbbb', '22222'), ('bbbbb', '3333
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;
如您所见,独特的子查询重复了两次。我可以通过使用WITH命令来避免这种情况,但我的理解是,这并不一定意味着子查询只执行一次。现在我来到StackOverflow,询问是否有人知道一种更有效的方式来运行这个查询 只需使用窗口函数即可。一种方法是将答案数与不同答案数进行比较:
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;
这将使用行号进行不同的计算。您可以将其简化为:
select *
from duplicates
where questionid in (select questionid
from duplicates
group by questionid
having count(distinct assignmentid) > 1);
子查询返回分配给多个assignmentid的所有QuestionId CTE(“with”)查询将执行一次。@没有名称的马请在CTE注释上展开。我认为CTE应该被视为视图(而不是临时表),这意味着每次使用视图时,都会重复对底层表的调用。也许我误解了。下面是我提到的另一个stackoverflow页面的链接:不幸的是,Postgres不支持窗口中的
distinct
functions@a_horse_with_no_name . . . 非常感谢。我很方便地忘记了SQL Server不是唯一存在此缺陷的数据库。
select *
from duplicates
where questionid in (select questionid
from duplicates
group by questionid
having count(distinct assignmentid) > 1);