连接两个sql表并分组
Posted
技术标签:
【中文标题】连接两个sql表并分组【英文标题】:Joining two sql tables and grouping 【发布时间】:2014-10-21 21:42:43 【问题描述】:我的数据库中有两个表:
汽车: IdCar PK, 公司, 类型, 颜色
出租: Id-rent_date PK, IdCar FK, Car_return_date
我需要编写一个返回三列的查询: - 年 - 当年租用特定公司汽车的天数 - 公司 - 来自 Cars 表
现在我有:
SELECT DATEDIFF(dd, Id-rent_date, Car_return_date) AS 天数,公司 FROM Renting INNER JOIN Cars ON Renting.IdCar = Cars.IdCar
我尝试在查询结束时按公司分组,但它返回错误:
选择列表中的“Renting.Id-rent_date”列无效,因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句中。
【问题讨论】:
【参考方案1】:如果您添加 group by
子句,则选择列表中的所有项目必须是您分组的列或聚合计算。例如,在这里,您想要总结每家公司的天数:
SELECT SUM(DATEDIFF(dd, Id-rent_date, Car_return_date)) AS Days,
Company
FROM Renting
INNER JOIN Cars ON Renting.IdCar = Cars.IdCar
GROUP BY Company
【讨论】:
太好了,这是我错过的东西,谢谢!现在我有好几天租每辆公司的车,我怎么能把它分成几年呢?在另一个选择中是否需要一些选择或类似的东西?【参考方案2】:这并不容易,因为您必须考虑 Id-rent_date 与 Car_return_date 不同的年份。 如果您假设 YEAR([Id-rent_date]) = YEAR(Car_return_date) 是
SELECT YEAR([Id-rent_date]), SUM(DATEDIFF(dd, [Id-rent_date], Car_return_date)) AS Days,
Company
FROM Renting
INNER JOIN Cars ON Renting.IdCar = Cars.IdCar
GROUP BY Company, YEAR([Id-rent_date])
【讨论】:
是的,这是一个问题,我正在考虑这种情况,我执行了查询:SELECT * FROM Renting WHERE YEAR(Id-rent_date) != YEAR(Car_return_date) 来测试有多少数据是相关的这个问题。【参考方案3】:完整查询:
declare @iter int
declare @max int
declare @test Table ([Id-rent_date] datetime, Car_return_date datetime, IdCar int)
set @iter = 0
select @max = max(year(Car_return_date) - year([Id-rent_date])) FROM Renting
WHILE(@iter < @max)
BEGIN
insert into @test
SELECT
DATEADD(yy, DATEDIFF(yy,0,[Id-rent_date]) + @iter, 0)
,DATEADD(yy, DATEDIFF(yy,0,[Id-rent_date]) + 1 + @iter, -1)
,IdCar
FROM Renting
where year([Id-rent_date]) + @iter <> year(Car_return_date) and year([Id-rent_date]) <> year(Car_return_date)
set @iter = @iter + 1
END
SELECT YEAR([Id-rent_date]), SUM(DATEDIFF(dd, [Id-rent_date], Car_return_date)) AS Days,
Company
FROM
(SELECT
[Id-rent_date]
,[Car_return_date]
,IdCar
FROM Renting
where year([Id-rent_date]) = year(Car_return_date)
union all
SELECT
[Id-rent_date]
,DATEADD(yy, DATEDIFF(yy,0,[Id-rent_date]) + 1, -1)
,IdCar
FROM Renting
where year([Id-rent_date]) <> year(Car_return_date)
UNION ALL
SELECT
DATEADD(yy, DATEDIFF(yy,0,[Car_return_date]), 0)
,[Car_return_date]
,IdCar
FROM Renting
where year([Id-rent_date]) <> year(Car_return_date)
UNION ALL
select * from @test) RentingSplit inner join Cars ON RentingSplit.IdCar = Cars.IdCar
GROUP BY Company, YEAR([Id-rent_date])
【讨论】:
没想到查询会这么复杂!它运行良好,谢谢! 如果您在 Car_return_date 字段中允许值为 NULL(汽车尚未归还),您应该使用 ISNULL(Car_return_date,getdate()) 而不是 Car_return_date。它应该看起来像 SUM(DATEDIFF(dd, [Id-rent_date], ISNULL(Car_return_date,getdate())))【参考方案4】:您需要将列名 id-rent_date 更改为 id_rent_date 因为 - 是保留字符,然后:
SELECT DATEDIFF(dd, Id_rent_date, Car_return_date)
AS Days,
DATEPART(yy, Car_return_date)
AS year, Company
FROM Renting
INNER JOIN Cars
ON Renting.IdCar = Cars.IdCar
GROUP BY Company
【讨论】:
以上是关于连接两个sql表并分组的主要内容,如果未能解决你的问题,请参考以下文章