连接两个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表并分组的主要内容,如果未能解决你的问题,请参考以下文章

SQL 连接两个表并检查两个表中的每个值是不是存在

连接两个表并显示发票编号总额的 SQL 查询

连接两个表并从一列返回多个匹配项的 SQL 查询?

在连接的情况下,条件是不是在 SQL 中分组是不是重要?

如何连接两个表并显示源?

连接 2 个表并计算 SQL 中特定字段的出现次数