我使用一个简单的存储过程从数据库中获取一些数据,到目前为止工作正常。
在SQL中是否有一种方法可以计算每个项目在我的选择结果中出现的频率,然后删除重复项,例如看着“url”栏目? 基本上我想添加到我的选择结果的每一行,然后理想地删除重复项。
示例: 我未经过滤的结果将是:url1,url1,url1,url2,url2,url3。 我希望看到的是: url1 3 url2 2 url3 1
我的存储过程:
**ALTER PROCEDURE [dbo].[CountQueue]
AS
BEGIN
SET NOCOUNT ON;
SELECT dateEsc,
url,
EID
FROM QueueLog
WHERE logStatus = 'New'
AND region = 'US'
AND (
flag = 'flag1'
OR
flag = 'flag2'
)
ORDER BY dateEsc desc, EID desc
END**
非常感谢Tim的任何帮助
答案 0 :(得分:2)
您可以在查询中执行此操作,而不必使用存储过程。如果我理解正确,您可以使用“分组依据”来解决问题。
SELECT url,
count(*)
FROM QueueLog
WHERE logStatus = 'New'
AND region = 'US'
AND (
flag = 'flag1'
OR
flag = 'flag2'
)
GROUP BY url;
如果您只想获得具有重复项的网址,可以添加:
SELECT url,
count(*)
FROM QueueLog
WHERE logStatus = 'New'
AND region = 'US'
AND (
flag = 'flag1'
OR
flag = 'flag2'
)
GROUP BY url
HAVING count(*) > 1;
我最喜欢的删除重复项的方法是使用windowing functions。无论哪种方式,要删除重复项,您必须知道要删除哪些副本。我假设您要删除具有较新dateEsc的那个。这里的查询(或类似的东西)应该为您提供所有重复的行。在您确认它们是正确的之后,将其从选择更改为删除并不困难。
SELECT * FROM
(
SELECT EID,
dateEsc,
url,
rank() OVER(PARTITION BY url ORDER BY dateEsc) as rank
FROM QueueLog
WHERE logStatus = 'New'
AND region = 'US'
AND (
flag = 'flag1'
OR
flag = 'flag2'
)
) a
WHERE a.rank > 1;
基本上,内部查询采用具有相同url的所有行,并根据dateEsc为它们提供排名。因此,具有最早dateEsc的那个将在等级列中获得“1”,下一个最老的将获得等级2,依此类推。然后我们知道我们想要保持等级为1-的那个 - 重复项将是等级2或更高的任何东西。所以我们在外部查询中选择那些行。如果您想更改条目是“正确的条目”,只需将rank() OVER(PARTITION BY url ORDER BY dateEsc) as rank
更改为rank() OVER(PARTITION BY url ORDER BY EID) as rank
或者这样。