SQL Server:计算选择结果中每个项目的外观

时间:2014-03-01 15:14:42

标签: sql sql-server stored-procedures count ranking

我使用一个简单的存储过程从数据库中获取一些数据,到目前为止工作正常。

在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的任何帮助

1 个答案:

答案 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 或者这样。