Sql server 从不同的两列中选择所有列
我需要在以下数据库中选择具有不同Sql server 从不同的两列中选择所有列,sql-server,group-by,unique,distinct,Sql Server,Group By,Unique,Distinct,我需要在以下数据库中选择具有不同'CP'的*where distinct'Rua': id Rua Local Conc CP 81143 dos moinhos Rio Tinto Gondomar 0123 81142 dos Moinhos Rio Tinto Gondomar 4435 81141 dos Moinhos
'CP'
的*where distinct'Rua'
:
id Rua Local Conc CP
81143 dos moinhos Rio Tinto Gondomar 0123
81142 dos Moinhos Rio Tinto Gondomar 4435
81141 dos Moinhos Rio Tinto Gondomar 4435
通过以下查询,我可以获得两列:
SELECT Rua, CP
FROM Codigo
GROUP BY Rua, CP
HAVING COUNT(*) = 1
但是我想要所有的专栏<代码>选择*返回“列'Codigo.id'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。”
所以我找到了这个答案:
我没有选择接受的答案,因为我需要一个快速查询(这将用于AJAX搜索建议)。我用了另一个投票率很高的答案。因此,我创建了以下查询:
SELECT * From Codigo
WHERE (Rua,CP) IN (
SELECT Rua, CP
FROM Codigo
GROUP BY Rua, CP
HAVING COUNT(*) = 1
);
返回在预期条件的上下文中指定的非布尔类型的表达式,接近“,”错误。为什么它期望WHERE
之后的Rua
为布尔值?在回答中,他们使用了saleprice
,这似乎不是布尔值
因此,我的问题是如何选择所有列,包括具有相同
Rua
和CP
的行,但这些行只能选择一次(DISTINCT
)?SQL Server不支持(val1,val2)语法中的(a,b)
使用EXISTS
检查该对
SELECT *
FROM Codigo C1
WHERE EXISTS (SELECT 1
FROM Codigo C2
WHERE C1.Rua = C2.Rua
AND C1.CP = C2.CP
HAVING Count(*) = 1);
或者使用COUNT()Over()
窗口聚合函数对每个Rua、CP
组合的记录进行计数,并筛选计数为1的组,以在每个不同的CP
中查找一行Rua
SELECT *
FROM (SELECT *,
Count(1)OVER(partition BY Rua, CP) AS cnt
FROM Codigo C1) A
WHERE cnt = 1
这将是我的首选方法,因为它比使用EXISTS
高效得多,优化器只需扫描/查找表一次
如果不希望重复记录,请使用行号()
我已使用Id
列订购了重复记录,并从重复记录中选择了第一条记录 使用窗口功能(单表读取):
使用EXISTS(读取表两次):
加入(再次加入两次):
两者都有效。第一个建议需要33秒,第二个建议需要3秒:)为什么会有这么大的差异?@Dillinger-因为优化器每秒钟只需要扫描/查找一次表。我想我没有正确地提出这个问题。我希望包含具有相同Rua
和CP
的行,但只包含一次。这样,我只得到没有重复的Rua
和CP
的结果。如果我编辑并修正我的问题,你会修正你的答案吗?@Dillinger-是的,当然。在存在中按
分组
方法是不需要的
SELECT *
FROM (SELECT *,
Row_Number()OVER(partition BY Rua, CP Order by id) AS RN
FROM Codigo C1) A
WHERE RN = 1
SELECT t.*
FROM
(SELECT t.*, COUNT(1) OVER (partition BY Rua, CP) AS cnt FROM Codigo t
) t
WHERE cnt = 1;
SELECT *
FROM Codigo t1
WHERE EXISTS
(SELECT 1
FROM Codigo t2
WHERE t1.Rua = t2.Rua
AND t1.CP = t2.CP
GROUP BY Rua, CP
HAVING COUNT(*) = 1
);
SELECT C1.*
FROM Codigo C1
INNER JOIN
(SELECT Rua, CP FROM Codigo C2 GROUP BY Rua, CP HAVING COUNT(*) = 1
) C2
ON C1.Rua = C2.Rua
AND C1.CP = C2.CP;