1

我被这个 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 昨天而不是今天出现的记录来获得排名 - 但后来我不知道如何获得 Count 了。

提前感谢您对此的任何帮助。

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

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

4 回答 4

2

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

因此,当您将排名添加到组时,组会比以前更多。

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

于 2011-02-25T21:42:05.820 回答
1

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

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

于 2011-02-25T21:49:21.117 回答
1

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

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
于 2011-02-25T22:11:01.713 回答
0

我不确定这是否是您的问题,我希望我有评论此问题的声誉,但是 group by 声明中的“排名”项是否必要?鉴于这种情况,它看起来不应该是这样。

于 2011-02-25T21:17:37.897 回答