聚合函数中的子查询

时间:2017-08-29 13:26:10

标签: sql tsql

说我有下表:

表1

ID    DATE         TYPE
001   2017-08-01   50
002   2017-08-01   40
003   2017-08-01   40
001   2017-05-01   50

我有另一张桌子 表2

ID   DATE          TYPE
001  2005-01-01    50
002  2010-10-11    30

并说我想使用一个case语句,它会使用子查询从另一个表中提取数据,如下所示:

SELECT 
   ID
  ,MAX(DATE)
  ,CASE WHEN TYPE = '50'
        THEN (
              SELECT MAX(DATE) 
              FROM table2 
              WHERE table1.ID = table2.ID
              ELSE '10' END
             )
FROM table1
GROUP BY ID

唯一的问题是,如果我有一个Group By:

,我就不能使用子查询
  

无法对包含的表达式执行聚合函数   聚合或子查询。

那么什么是好的选择?

3 个答案:

答案 0 :(得分:2)

您看到的错误只是问题的一部分。第一个问题是在TYPE语句中单独使用CASE列。想象一下你有这些数据:

ID   TYPE
 1     49
 2     50
 2     51

您正在ID进行分组,然后检查群组外的TYPE。 ID#1没问题,但数据库应该用ID#2做什么?它是否应符合案件条件?

现在,您和我都从您的示例数据中知道这不会发生。在table1示例数据中,组中的所有记录都具有相同的Type值。但数据库无法知道。您没有理由不能将记录更新为单Type的混合ID值,因此数据库引擎不允许这样做。

您需要在TYPE子句中包含GROUP BY列,或将其与聚合函数一起使用。如果你可以做后者,那应该是“固定”该记录的值,并允许你使用你的子查询...如果这是你真正想要的。无论如何,你可以用JOIN或APPLY做得更好。

答案 1 :(得分:1)

改为使用连接:

SELECT t.id,MAX(t.date), COALESCE(s.max_date,DefaultDateHerE) as max_date_t2
FROM table1 t
LEFT JOIN(SELECT p.id,MAX(p.date) as max_date
          FROM Table2
          GROUP BY p.id) s
 ON(s.id = t.id)
GROUP BY t.id,COALESCE(s.max_date,DefaultDateHerE)

答案 2 :(得分:0)

尝试 LEFT JOIN 并在“ON”语句中添加过滤器table2.Type = 50

SELECT table1.ID,
   max(table1.[DATE]) [table1.DATE],
   max(table2.[DATE]) [table2.DATE]
FROM (VALUES ('001','2017-08-01','50')
    ,('002','2017-08-01','40')
    ,('003','2017-08-01','40')
    ,('001','2017-05-01','50')
    ) table1([ID],[DATE],[TYPE])
    LEFT JOIN 
        (
        VALUES ('001','2005-01-01','50')
                ,('002','2010-10-11','30')
        ) table2([ID],[DATE],[TYPE]) ON table1.ID = table2.ID
        and table2.Type = 50
GROUP BY table1.ID