1

假设我有下表。如果我只想返回非活动行(活动 = 0)但忽略具有相同文件名的字段。例如,查询应该只返回 Helper0990329,因为它处于非活动状态并且在另一行中没有其他相同的文件名。VinnyVincenzo1345090457296 不应包含在结果中。

PATH          |         FileName         |   Active                       
C:\Vinny\     VinnyVincenzo1345090457296.mp3    0
C:\Vinny\     VinnyVincenzo1345090457296.mp3    1
C:\Vinny\     VinnyVincenzo1345137702505.mp3    1
C:\Helper\    Helper0990329.mp3                 0

我尝试了以下操作,但最终停用了(然后删除了)我不应该拥有的文件:

SELECT 

      [Path],
      [FileName]

  FROM [Flows].[dbo].[Flows_Flows]
  Where [Active] = '0' AND [Created] > '8/18/2012'
  Group By Path, FileName
  Having count(FileName) = 1
  GO
4

4 回答 4

0

假设您使用的是 SQL 2005 或更高版本,您可以使用排名函数来解决此问题:

select *
from (SELECT [Path], [FileName],
             count(*) over (partition by path, filename) as numFiles
      FROM [Flows].[dbo].[Flows_Flows]
      Where [Created] > '8/18/2012'
     ) t
where active = 0 and numfiles = 1

我们查询的问题是 WHERE 子句在 HAVING 子句之前被评估。因此,从未见过活动行。

或者,您可以使用简单的 group by 但更复杂的 HAVING 子句来做到这一点:

SELECT [Path], [FileName]
FROM [Flows].[dbo].[Flows_Flows]
Where [Created] > '8/18/2012'
Group By Path, FileName
Having count(FileName) = 1 and
       sum(case when Active = '0' then 1 else 0 end) = 1
于 2012-08-21T02:34:49.053 回答
0

通过计算其内部实例的数量来尝试它SubQuery

SELECT  [Path], [FileName]
FROM    Flows_Flows a 
            INNER JOIN 
            (
                SELECT  [FileName],
                        COUNT([FileName]) TotalCount
                FROM    Flows_Flows
                GROUP BY [FileName]
            ) b ON a.[FileName] = b.[FileName]
WHERE   a.[Active] = 0 AND
        a.[Created] > '8/18/2012' AND
        b.TotalCount = 1
于 2012-08-21T02:34:55.067 回答
0

我猜你也有一个 id 字段,对吧?我还假设您不一定只想要那些不重复的用户,而是那些没有任何活动条目的用户。

您可以IN在 WHERE 子句中使用。

例子:

SELECT Path, FileName FROM Flows_Flows WHERE Active = 0 AND id NOT IN
( SELECT id FROM Flows_Flows WHERE Active = 1 )
于 2012-08-21T02:39:22.310 回答
0

You can use a LEFT OUTER JOIN and when the join finds a duplicate row, exclude it (dup.path is null).

SELECT 
      f.[Path],
      f.[FileName]
FROM [Flows].[dbo].[Flows_Flows] f
LEFT OUTER JOIN [Flows].[dbo].[Flows_Flows] dup on f.Path = dup.Path and dup.Active = '1' --Active must be set otherwise, we found ourselves
Where f.[Active] = '0' AND f.[Created] > '8/18/2012'
  AND dup.Path is null -- here we exculde all rows that have a duplicate

The advantage being that this solution has no sub query nor aggregate. That being said, not having looked at the query plan, I cannot say if it is indeed faster. (I also just prefer this syntax, I suppose.)

于 2012-08-21T02:58:48.473 回答