如何在 SQL Server 2012 中使用 GROUP BY
How do I use GROUP BY in SQL Server 2012
我有两个表,一个包含垃圾箱列表,第二个包含收集该垃圾箱的工作日。
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')
我想要做的是 return 所有垃圾箱及其下一个收集日的列表。
我已经创建了这个查询,如果 return 是下一个收集日期,但它只 return 是一次只有一个垃圾箱的下一个收集日期。我不想 运行 对数据库中的每个 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 1
和 b.id = 1
条件,它将 return 每个工作日的所有垃圾箱和下一个日期。如果我尝试使用 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
关于如何在单个查询中 return 每个垃圾箱的下一个收集日期有什么想法吗?
编辑:使用连接和其他内容更新了查询
应该这样做
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 查询中包含字段,这些查询要么包含在组子句中,要么传递到聚合函数(如 Min 或 max)中。由于 Name 可能不是唯一的,我们不能不对它进行分组。
为了解决这个问题,我们获取返回的 ID 和日期的结果集,并将其加入 Bin table 以获取 bin 名称。
我有两个表,一个包含垃圾箱列表,第二个包含收集该垃圾箱的工作日。
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')
我想要做的是 return 所有垃圾箱及其下一个收集日的列表。
我已经创建了这个查询,如果 return 是下一个收集日期,但它只 return 是一次只有一个垃圾箱的下一个收集日期。我不想 运行 对数据库中的每个 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 1
和 b.id = 1
条件,它将 return 每个工作日的所有垃圾箱和下一个日期。如果我尝试使用 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
关于如何在单个查询中 return 每个垃圾箱的下一个收集日期有什么想法吗?
编辑:使用连接和其他内容更新了查询
应该这样做
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 查询中包含字段,这些查询要么包含在组子句中,要么传递到聚合函数(如 Min 或 max)中。由于 Name 可能不是唯一的,我们不能不对它进行分组。
为了解决这个问题,我们获取返回的 ID 和日期的结果集,并将其加入 Bin table 以获取 bin 名称。