【问题标题】:SQL Server: count appearance of each item in select resultsSQL Server:计算选择结果中每个项目的出现次数
【发布时间】:2014-04-02 16:39:12
【问题描述】:

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

SQL 中有没有一种方法可以计算每个项目在我的选择结果中出现的频率,然后删除重复项,例如查看“url”列? 基本上我想添加到我的选择结果的每一行,然后理想地删除重复项。

示例: 我未经过滤的结果是:url1、url1、url1、url2、url2、url3。 我想看到的是: 网址1 3 网址2 2 网址3 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**

非常感谢您对蒂姆的任何帮助

【问题讨论】:

  • 根据你的描述,我不明白为什么 SELECT DISTINCT 不起作用,但我怀疑你在你的问题中遗漏了细节,说明为什么这是不够的。

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


【解决方案1】:

您可以在查询中执行此操作,而不必使用存储过程。如果我理解正确,您可以使用“分组依据”来解决问题。

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 之类的。

【讨论】:

  • 非常感谢 - 这太好了,解释很有帮助!
猜你喜欢
  • 1970-01-01
  • 2011-12-27
  • 2012-08-05
  • 1970-01-01
  • 2012-08-06
  • 1970-01-01
  • 2013-08-22
  • 1970-01-01
  • 2011-07-02
相关资源
最近更新 更多