Sql server 2008 SQL Select-添加要选择的字段正在更改结果

Sql server 2008 SQL Select-添加要选择的字段正在更改结果,sql-server-2008,having-clause,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

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


再次感谢大家

我不确定这是否是你的问题,我希望我有资格评论这一点,但“按声明分组”中的排名项目是否有必要?在这种情况下,它看起来不应该是这样。

我不确定这是否是你的问题,我希望我有评论这一点的声誉,但是否有必要按声明在组中排名?在这种情况下,它看起来不像是应该的。

问题可能是,对于第一个问题中会分组的项目,排名是不同的

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


如果是这种情况,并且您仍然需要相同数量的行,那么您必须在分组后使用包装问题包含排名,然后您还必须确定您喜欢匹配行中的最小排名还是最大排名。

问题可能是,对于第一个问题中要分组的项目,排名不同

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


如果是这种情况,并且您仍然需要相同数量的行,那么您必须在分组后使用包装问题包含排名,然后您还必须确定您喜欢匹配行中的最小排名还是最大排名。

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


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

您的初始查询没有按三个字段对组进行排序。 添加排名后,您的查询按四个字段分组。 因此,您的分组是按更细的粒度进行的,因此很可能会提供更多的记录


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

您可以计算计数,而无需使用Group 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

您可以不使用GROUPBY 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

对从逻辑角度来看,我会同意,但如果我没有包括每个字段,我会得到错误的“列”表。排名“在选择列表中无效,因为它既不包含在聚合函数中,也不包含在GROUP BY子句中。”它是否返回包含每天存储的排名的结果?您可能需要创建一个视图,该视图按照从表中选择ranking、itemid、listid,其中day=dayeday,然后通过itemid和listid.Yes连接该视图上的查询结果。从逻辑角度来看,我会同意,但如果我没有包括每个字段,我会得到错误的“列”表。排名“在选择列表中无效,因为它既不包含在聚合函数中,也不包含在GROUP BY子句中。”它是否返回包含每天存储的排名的结果?您可能需要创建一个视图,该视图按照从表中选择ranking、itemid、listid,其中day=Dayed,然后根据itemid和listid在该视图上加入查询结果。每个列表中的每个项目每天只能显示一次,同样,每个排名只能显示一次,因此我认为min和max不会成为问题。“包装问题”是指在没有rankin的情况下获取第一组结果吗

并将其作为更大查询中的子查询?这听起来像是一种我可以尝试的方法。我会试试,然后再打给你。谢谢你的指点。成功!我将把工作查询附加到问题中,并尝试描述我所做的最好的事情,以防这对将来的某人有所帮助。谢谢你,大卫…这正是我需要解决的问题!每个项目每天只能在列表中出现一次,同样,每个排名也只能出现一次,所以我不认为最小值和最大值会成为问题。“包装问题”是指在不排名的情况下获取第一组结果,并将其作为更大查询中的子查询吗?这听起来像是一种我可以尝试的方法。我会试试,然后再打给你。谢谢你的指点。成功!我将把工作查询附加到问题中,并尝试描述我所做的最好的事情,以防这对将来的某人有所帮助。谢谢你,大卫…这正是我需要解决的问题!不确定发布数据集的最佳方式,但也许我可以更好地描述它。最简单的形式是,每天有n个排名项目的列表。一个项目可以在某一天出现在排名x的位置,第二天出现在排名y的位置,并在第3天从列表中删除。项目不能在同一天在同一列表中出现两次。假设我的原始查询返回了列表中昨天出现但今天没有出现的100个项目中的3个。我已经证实这是正确的。我的第二个排名查询返回77个项目。昨天的排名是正确的,但大部分是今天出现的,因此Maxdate显然不再正常工作。我怀疑出现额外的记录是因为这两天的排名不同,那些没有保持相同排名的人…如果有帮助的话。我不确定发布数据集的最佳方式,但也许我可以更好地描述它。最简单的形式是,每天有n个排名项目的列表。一个项目可以在某一天出现在排名x的位置,第二天出现在排名y的位置,并在第3天从列表中删除。项目不能在同一天在同一列表中出现两次。假设我的原始查询返回了列表中昨天出现但今天没有出现的100个项目中的3个。我已经证实这是正确的。我的第二个排名查询返回77个项目。昨天的排名是正确的,但大部分都是在今天出现的,因此Maxdate显然不再正常工作。我怀疑出现额外的记录是因为这两天的排名不同,而那些没有保持相同排名的记录……如果有帮助的话。Thomas,我还不熟悉Over条款,但我正在寻找。同时,我尝试在SSMS中运行此功能,但出现了几个错误。首先,你的意思是把两个Where从句一个接一个地放进去,还是第二个从句应该是And?此外,底部的DaysOnList并没有从顶部的定义中被识别出来,但这可能是相关的。最后,T在中心Select中不被识别,但我能够使它作为一个自连接工作……只是不确定这是否按照您的意图破坏了查询的其余部分。谢谢。@nycdan-那是个打字错误的替身。应该有一个And There。@nycdan-我不确定它为什么不喜欢T别名。从我看来,这是正确的。第二个select不是自联接,而是与自身相关的子查询,以确保给定项和列表中没有日期大于昨天的值。这相当于你的HavingMaxDate=Beday逻辑。Thomas,我让它如上所述工作,但我仍然有兴趣学习如何使它工作。谢谢你的指点,如果我有时间的话,这会给我一些其他的东西来学习@nycdan-Over子句是一个窗口函数,它允许您在不使用正式Group By的情况下对数据子集进行操作。Row_Number,创建分区列表中每个分组的连续数字列表,因此在每个新组上,它会重新启动并计数。显然,它的工作方式与正常情况相同,只是它会重新启动对每个新组的计数。使用Row_Number的原因是为了确保每个ItemId、ListId和ItemName组只获得一行,因为我不再使用group By.Thomas,我还不熟悉Over子句,但正在查找。同时,我尝试在SSMS中运行此功能,但出现了几个错误。首先,你的意思是把两个Where从句一个接一个地放进去,还是第二个从句应该是And?此外,底部的DaysOnList并没有从顶部的定义中被识别出来,但这可能是相关的。最后,T在中心Select中不被识别,但我能够使它作为一个自连接工作……只是不确定这是否按照您的意图破坏了查询的其余部分。谢谢。@nycdan-那是个打字错误的替身。应该有一个And There。@nycdan-我不确定它为什么不喜欢T别名。从我看来,这是正确的。第二个select不是自连接,而是与自身相关的子查询,以确保
对于给定的项目和列表,没有日期大于昨天的值。这相当于你的HavingMaxDate=Beday逻辑。Thomas,我让它如上所述工作,但我仍然有兴趣学习如何使它工作。谢谢你的指点,如果我有时间的话,这会给我一些其他的东西来学习@nycdan-Over子句是一个窗口函数,它允许您在不使用正式Group By的情况下对数据子集进行操作。Row_Number,创建分区列表中每个分组的连续数字列表,因此在每个新组上,它会重新启动并计数。显然,它的工作方式与正常情况相同,只是它会重新启动对每个新组的计数。使用Row_Number的原因是为了确保每个ItemId、ListId和ItemName组只获得一行,因为我不再使用groupby。