【问题标题】:How do I use GROUP BY in SQL Server 2012如何在 SQL Server 2012 中使用 GROUP BY
【发布时间】:2021-02-15 13:23:14
【问题描述】:

我有两张表,一张包含垃圾箱列表,第二张包含收集垃圾箱的工作日。

declare @bins table (
    id int IDENTITY(1,1) PRIMARY KEY,
    name nvarchar(255),
    collectionCode nvarchar(255)
)

declare @collectionDays table (
    id int IDENTITY(1,1) PRIMARY KEY,
    weekday int,
    collectionCode nvarchar(255)
)

insert into @bins (name, collectionCode) values
('Bin 1','MWF'),
('Bin 2','MWF'),
('Bin 3','ED'),
('Bin 4','ED'),
('Bin 5','ED'),
('Bin 6','ED'),
('Bin 7','ED'),
('Bin 8','ED'),
('Bin 9','ED'),
('Bin 10','MWF')

insert into @collectionDays (weekday, collectionCode) values
(0,'MWF'),
(2,'MWF'),
(4,'MWF'),
(0,'ED'),
(1,'ED'),
(2,'ED'),
(3,'ED'),
(4,'ED'),
(5,'ED'),
(6,'ED')

我想做的是在下一个收集日返回所有垃圾箱的列表。

我已经创建了这个查询,如果返回下一个收集日期,但它一次只返回一个垃圾箱的下一个收集日期。我不想为数据库中的每个 bin 运行此查询。

这是我的查询

select top 1
    name,
    format(dateadd(day, (datediff(day, weekday, getdate()) / 7) * 7 + 7, weekday), 'dd/MM/yyyy') AS date
from @bins b
join @collectionDays c on b.collectionCode = c.collectionCode
where b.id = 1
order by date asc

如果我删除 top 1b.id = 1 条件,它将返回每个工作日的所有垃圾箱和下一个日期。如果我尝试使用group by,则会收到错误Column '@collectionDays.weekday' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

select
    name,
    format(dateadd(day, (datediff(day, weekday, getdate()) / 7) * 7 + 7, weekday), 'dd/MM/yyyy') AS date
from @bins b
join @collectionDays c on b.collectionCode = c.collectionCode
group by b.id
order by date asc

关于如何在单个查询中返回每个垃圾箱的下一个收集日期有什么想法吗?

编辑:使用 join 和其他内容更新查询

【问题讨论】:

  • 你为什么想要使用GROUP BY,你的查询中没有任何聚合。另外,为什么你仍然使用那个 32 岁的语法?它在 1992 年被显式的 JOIN 语法所取代;到现在为止,您已经有 29 年的时间来采用它了;你真的应该这样做。
  • 进化——没有人应该使用old-style joins
  • @Larnu 谢谢你,我已经用连接语法更新了这个问题。关于格式,工作日中的数字表示0是星期一,3是星期三,6是星期日等等
  • 我误读了格式,抱歉。不过,我建议使用CONVERT 和样式代码103;它要快得多。

标签: sql-server group-by sql-server-2012


【解决方案1】:

应该这样做

select
    name,
    MIN(format(dateadd(day, (datediff(day, weekday, getdate()) / 7) * 7 + 7, weekday), 'dd/MM/yyyy')) AS [DATE]
from @bins b
join @collectionDays c on b.collectionCode = c.collectionCode
group by name
order by date asc

基本上,您希望按名称分组,因为这是您返回的结果之一,然后获取每个名称返回的最短日期。

对于此示例,名称似乎是唯一的。在很多情况下,这并不能保证,所以你想做这样的事情

;with cte_nextdates as
(
select
    b.id,
    MIN(format(dateadd(day, (datediff(day, weekday, getdate()) / 7) * 7 + 7, weekday), 'dd/MM/yyyy')) AS [DATE]
from @bins b
join @collectionDays c on b.collectionCode = c.collectionCode
group by b.id
)
SELECT B.name,
[date]
FROM cte_nextdates ND
INNER JOIN @bins B ON B.id = ND.id
order by date asc

这样做是根据 ID 而不是名称进行分组。

问题是您只能在分组的 SQL 查询中包含字段,这些查询要么包含在 group 子句中,要么传递到像 Min 或 max 这样的聚合函数中。由于名称可能不是唯一的,我们不能不对其进行分组。

为了解决这个问题,我们获取返回的 ID 和日期的结果集,并将其加入 Bin 表以获取 bin 名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    • 2021-09-28
    • 2010-09-21
    相关资源
    最近更新 更多