SQL Select - 添加字段到 Select 正在改变结果
我被这个 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
基本上,我所做的是创建一个子查询,查找这两天出现的所有项目,并查找昨天出现但在不在这两天出现的一组项目中。然后我就能够正确执行聚合函数和分组。如果这比必要的更复杂,我不会感到惊讶,但我理解它并且可以根据需要修改它,并且性能似乎不是问题。
再次感谢大家!
I'm stumped by this SQL problem that I suspect will be easy pickings for someone out there.
I have a table that contains rows representing several daily lists of ranked items. The relevent fields are as follows: ID, ListID, ItemID, ItemName, ItemRank, Date.
I have a query that returns the items that were on a list yesterday but not today (Items Off List) as follows:
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)
Basically I'm looking for records where the max date is yesterday. It works fine and shows the number of days each item was previously on the list (although not necessarily consecutively, but that's fine for now).
The problem is when I try to add ranking to see what yesterday's rank was. I tried the following:
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)
This returns a great deal more records than the previous query so something isn't right with it. I want the same number of records, but with the ranking included. I can get the rank by doing a self-join with a subquery and getting records where the ItemID occurs yesterday but not today - but then I don't know how to get the Count any more.
Appreciation in advance for any help with this.
======== SOLVED ==============
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
Basically, what I did was create a subquery that finds all items that appear in both days, and finds items that appeared yesterday but are not in the set of items that appeared both days. Then I was able to do the aggregate function and grouping correctly. I would NOT be surprised if this is more convoluted than necessary but I understand it and can modify it as needed and performance doesn't seem to be an issue.
Thanks to all again!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题可能是第一个问题中分组的项目的排名不同。
因此,当您向组添加排名时,组数会比以前更多。
如果是这种情况,并且您仍然想要相同数量的行,则必须在使用包装问题进行分组后包含排名,然后您还必须决定是否喜欢匹配行的最小排名或最大排名。
The problem probably is that ranking is different for items that would in the first question get grouped.
So when you add ranking to the group by there are more groups than before.
If this is the case and you still want the same amount of rows you have to include ranking after grouping witn a wrapping question and then you also have to decide if you like min ranking or max ranking from the matching rows.
您的初始查询没有按三个字段对分组进行排名。
添加了排名的查询按四个字段进行分组。
因此,您的分组是按更细粒度进行的,因此很可能会为您提供更多记录。
在建议查询解决方案之前,我需要查看示例数据集和示例所需值。
Your initial query without ranking groups by three fields.
Your query, with the ranking added, groups by four fields.
So your grouping is by a finer grain and will therefore most likely give you more records.
I would need to see a sample dataset and sample desired values before suggestion a query solution.
您可以在不使用 Group By Over 子句的情况下计算计数。
You could calculate the Count without using a Group By by the Over clause.
我不确定这是否是您的问题,我希望我有评论这一点的声誉,但是按声明分组中的“排名”项是否有必要?鉴于这种背景,它看起来不应该是这样。
I'm not sure if this is your problem, and I wish I had the reputation to comment this, but is the "ranking" item in the group by statement necessary? Given this context, it doesn't look like it should be.