SQL Select - 向Select添加字段正在更改结果

时间:2011-02-25 21:12:04

标签: sql-server-2008 having-clause

我对这个SQL问题感到困惑,我怀疑这个问题对于那些人来说很容易找到。

我有一个表,其中包含代表几个每日排名项列表的行。相关字段如下:ID,ListID,ItemID,ItemName,ItemRank,Date。

我有一个查询,它返回昨天列表中的项目但不是今天(项目关闭列表),如下所示:

Select ItemID, ListID, ItemName, convert(varchar(10),MAX(date),101) as date, COUNT(ItemName) as days_on_list 
From Table 
Group By ItemID, ListID, ItemName
Having Max(date) = DATEADD("d",-1,convert(varchar(10),getdate(),101)) and ListID = 1
Order By ListID, ItemName, COUNT(ItemName)

基本上我正在寻找最大日期是昨天的记录。它工作正常,并显示每个项目之前在列表中的天数(虽然不一定是连续的,但现在还可以。)

问题是当我尝试添加排名以查看昨天的排名时。我尝试了以下方法:

Select ItemID, ListID, ItemName, ranking, convert(varchar(10),MAX(date),101) as date, COUNT(ItemName) as days_on_list 
From Table
Group By ItemID, ListID, ItemName, ranking
Having Max(date) = DATEADD("d",-1,convert(varchar(10),getdate(),101)) and ListID = 1
Order By ListID, ItemName, ranking, COUNT(ItemName)

这会返回比上一个查询多得多的记录,所以有些东西不合适。我想要相同数量的记录,但包括排名。我可以通过使用子查询进行自我连接并获取昨天但不是今天的ItemID记录来获得排名 - 但后来我不知道如何获得计数。

提前感谢任何帮助。

========已解决==============

Select ItemID, ListID, ItemName, ranking, convert(varchar(10),MAX(date),101) as date, (Select COUNT(ItemName) From Table T3 Where T3.ItemID = T.ItemID and T3.ListID = 1) as days_on_list
from Table T
Where date = DATEADD("d",-1,convert(varchar(10),getdate(),101)) and ListID = 1 and T.ItemID Not In
(select T.ItemID from Table T
    join Table T2 on T.ItemID = T2.ItemID and T.ListID = T2.ListID
    where T.date = DATEADD("d",-1,convert(varchar(10),getdate(),101)) and T2.date = convert
(varchar(10),getdate(),101) and T.ListID = 1)
Group by ItemID, ListID, ItemName, ranking

基本上,我所做的是创建一个子查询,查找在两天中出现的所有项目,并查找昨天出现的项目但不在两天出现的项目集合中。然后我能够正确地进行聚合功能和分组。如果这比必要的更复杂但我理解并且可以根据需要修改它并且性能似乎不是问题,我不会感到惊讶。

再次感谢所有人!

4 个答案:

答案 0 :(得分:2)

问题可能是第一个问题被分组的项目的排名不同。

因此,当您通过比以前更多的组添加排名时,

如果是这种情况,并且您仍然需要相同数量的行,则必须在分组包装问题后进行分组,然后您还必须决定是否喜欢匹配行中的最小排名或最高排名。

答案 1 :(得分:1)

您的初始查询没有按三个字段对组进行排名。 添加了排名的查询按四个字段分组。 因此,您的分组更精细,因此很可能会给您更多记录。

在建议查询解决方案之前,我需要查看示例数据集并对所需的值进行采样。

答案 2 :(得分:1)

您可以在不使用Over子句的Group By的情况下计算Count。

With Items As
    (
    Select ItemID, ListID, ItemName, Ranking, [Date]
        , Row_Number() Over( Partition By ItemID, ListID, ItemName Order By [Date] Desc ) As Num
        , Count(ItemName) Over ( Partition By ItemId, ListId, ItemName ) As DaysOnList
    From Table As T
    Where T.[Date] = DateAdd(d, -1, CURRENT_TIMESTAMP) 
        And Not Exists  (
                        Select 1
                        From Table As T2
                        Where T2.ItemID = T.ItemID
                            And T2.ListId = T.ListId
                            And T2.[Date] > T.[Date]
                        )
    )
Select ItemID, ListID, ItemName, LastDate, Ranking
From Items
Where Num = 1
Order By ListID, ItemName, DaysOnList

答案 3 :(得分:0)

我不确定这是不是你的问题,我希望我有这个评论的声誉,但是必须在声明组中的“排名”项目吗?鉴于这种情况,它看起来不应该是。