我们如何选择不在group by子句中的列

时间:2018-03-13 02:06:00

标签: sql-server tsql

我们如何选择不在GROUP BY子句中的列?

执行以下代码时,我收到错误:

  

聚合可能不会出现在WHERE子句中,除非它在a中   包含在HAVING子句或选择列表中的子查询以及列   被聚合是一个外部参考。

SELECT DISTINCT T012.hr_empl_code
    ,T012.hr_taxs_code
    ,max(T012.hr_efec_dati) AS last_hr_efec_dati
FROM hrtempnm T000
INNER JOIN hrtemptx T012 ON T000.hr_empl_code = T012.hr_empl_code
WHERE T000.hr_stus_code LIKE 'e%'
    AND T000.hr_stus_code <> 'epla'
    AND T000.hr_efec_dati = max(T000.hr_efec_dati)
GROUP BY T012.hr_empl_code
    ,T000.hr_efec_dati
    ,T012.hr_taxs_code
HAVING T000.hr_efec_dati = max(T000.hr_efec_dati)
ORDER BY 1,2

2 个答案:

答案 0 :(得分:0)

你的问题在于你的WHERE条款,第三个条件:

AND T000.hr_efec_dati = max(T000.hr_efec_dati)

在这里,您将引用聚合函数MAXWHERE子句在开始任何分组之前过滤数据,因此您无法在此处使用聚合函数,这是HAVING子句的用途。

WHERE子句中删除该条件,它将起作用(您已在HAVING子句中使用它。)

对于您的问题,只有两种方法可以选择GROUP BY中未提及的列:

  • 它是一个集合函数,如MAXMINAVG(或自定义函数)。
  • 它是一个常量值(硬编码或@变量),或表达式返回一个常量值,并且不引用任何未按其分组的列。

如果要查看特定组的列值,则应使用分组集的结果,并通过按列分组再次将其与表连接。像这样:

;WITH GroupedValues AS
(
    SELECT -- Remove the DISTINCT if you are already grouping by the same columns
        T012.hr_empl_code
        ,T012.hr_taxs_code
        ,max(T012.hr_efec_dati) AS last_hr_efec_dati
    FROM hrtempnm T000
    INNER JOIN hrtemptx T012 ON T000.hr_empl_code = T012.hr_empl_code
    WHERE T000.hr_stus_code LIKE 'e%'
        AND T000.hr_stus_code <> 'epla'
    GROUP BY T012.hr_empl_code
        ,T000.hr_efec_dati
        ,T012.hr_taxs_code
    HAVING T000.hr_efec_dati = max(T000.hr_efec_dati)
    -- remove the ORDER BY when used in a subquery (without TOP)
)
SELECT
    T012.hr_empl_code,
    T012.hr_taxs_code,

    UnGroupedColumn1,
    UnGroupedColumn2

FROM
    hrtempnm T000
    INNER JOIN hrtemptx T012 ON T000.hr_empl_code = T012.hr_empl_code
    INNER JOIN GroupedValues AS G ON 
        T012.hr_empl_code = G.hr_empl_code AND
        T012.hr_taxs_code = G.hr_taxs_code

答案 1 :(得分:0)

我相信这样做会......

WITH sequenced_data as 
(
select DISTINCT
    T000.hr_empl_code, 
    T012.hr_taxs_code, T012.hr_efec_dati,
    Rank() over (Partition BY T000.hr_empl_code order by T012.hr_efec_dati  DESC) as Rankx
    --,T012.hr_efec_dati
FROM 
    hrtempnm T000, 
    hrtemptx T012
WHERE   
    T000.hr_empl_code = T012.hr_empl_code
AND T000.hr_stus_code LIKE 'e%' AND T000.hr_stus_code <> 'epla'
) 

SELECT
  *
FROM
  sequenced_data
WHERE
  Rankx = 1