【问题标题】:Joining two sql tables and grouping连接两个sql表并分组
【发布时间】: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 子句中。

【问题讨论】:

    标签: sql 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-09
      • 1970-01-01
      • 2016-11-10
      • 2021-03-19
      • 2012-02-28
      • 2012-05-01
      • 1970-01-01
      • 2019-03-09
      相关资源
      最近更新 更多