自定义GROUP BY子句

时间:2016-03-18 08:22:41

标签: sql sql-server tsql

示例数据

假设我有这样的表:

No    Company     Vendor    Code   Date
1     C1          V1        C1     2016-03-08  
1     C1          V1        C1     2016-03-07
1     C1          V1        C2     2016-03-06  

渴望的OUPUT

期望的输出应该是:

No    Company     Vendor    Code   Date
1     C1          V1        C1     2016-03-08 

Date最多No, Company, Vendor(按这些列分组)。但是不应该按Code进行分组,必须考虑Date

QUERY

SQL查询如:

.....

LEFT JOIN (
    SELECT No_, Company, Vendor, Code, MAX(Date)
    FROM tbl 
    GROUP BY No_, Company, Vendor, Code
) t2 ON t1.Company = t2.Company and t1.No_ = t2.No_

.....

现在输出

但我现在得到了输出:

No    Company     Vendor    Code   Date
1     C1          V1        C1     2016-03-08  
1     C1          V1        C2     2016-03-06  

因为Code记录不同,但在这种情况下应该采用C1代码(因为No, Company, Vendor match

我做了什么

我尝试从Code子句中删除GROUP BY并使用SELECT MAX(Code)...,但这是错误的,因为它按字母顺序排列Code更高。

您有什么想法我能实现吗?如果不清楚我可以解释更多。

4 个答案:

答案 0 :(得分:4)

如果您的表没有任何标识列,则每行都由其具有的所有列值组合标识。这给我们带来了奇怪的on陈述。它包括我们分组的所有列和给定元组(No_, Company, Vendor)的最大值。

select t1.No_, t1.Company, t1.Vendor, t1.Code, t1.Date 
from tbl t1 
join (select No_, Company, Vendor, MAX(Date) as Date 
    from tbl 
    group by No_, Company, Vendor) t2
on t1.No_ = t2.No_ and 
   t1.Company = t2.Company and 
   t1.Vendor = t2.Vendor and 
   t1.Date = t2.Date 

看看this similar question

修改

  

感谢您的回答,但这会重复一次。假设可能存在等于No,Company,Vendor和Date的行,其他一些列则不同,但不在乎。所以使用INNER SELECT一切都很好,它返回不同的值,但是在加入t1时会产生问题,因为它有多个值。

然后您可能对rankrow_number这样的tsql结构感兴趣。看看Ullas' answer。试试rank,它可以提供略微不同的输出,可能符合您的需求。

答案 1 :(得分:2)

如果1个日期只能有1条记录,那么您可以先搜索最大日期查询,然后再检查。

select No_, Company, Vendor, Code, Date
FROM tbl
where Date in
    (select MAX(Date) from tbl GROUP BY No_, Company, Vendor)

如果有超过1行可能具有相同的日期,那么您可以使用partition

with cte as
(
select *, ROW_NUMBER() over(partition by No_, Company, Vendor order by Date DESC) as rn
from tbl
)
select No_, Company, Vendor, Code, Date
from cte
where rn=1

答案 2 :(得分:2)

您可以按row_numberNoVendor分区Date,并按日期降序排序。

<强>查询

;with cte as (
    select rn = row_number() over(
        partition by [No], Company, Vendor
        order by [Date] desc
    ), *
    from tbl
)
select [No], Company, Vendor, Code, [Date] from cte
where rn = 1; 

答案 3 :(得分:1)

Common Table Expression将为您完成。

WITH cte(N,C,V,D)
AS
(
SELECT t1.[No]
      ,t1.[Company]
      ,t1.[Vendor]
      ,MAX(t1.[Date])
  FROM [MyTest] t1
  GROUP BY t1.[No]
      ,t1.[Company]
      ,t1.[Vendor]
 )
 SELECT N,C,V,t2.Code,D 
 FROM cte c
 INNER JOIN MyTest t2 ON c.N = t2.No AND c.C = t2.Company AND c.V = t2.Vendor AND c.D = t2.Date