SQL Query从列表中为每种类型提取前1个值?

时间:2017-05-04 13:56:00

标签: sql sql-server-2008

我的数据库中有每个产品的不同类型的表。我想根据该类型为每个产品提取前1条记录。这是我目前的查询:

SELECT 
    dh_type, 
    dh_product
FROM myProducts
WHERE dh_productid = '08-BLD4011603S0'
    AND dh_type IN ('New','Old','Ref')
ORDER BY dh_createDt DESC

每种类型都可以包含在不同日期创建的多个产品。我想为每种类型提取最高记录(基于创建日期的最新记录)。一个用于新的,一个用于旧的,一个用于参考。我想知道在SQL中最好和最有效的方法是什么?当前查询将为每种类型提取多条记录,我只需要一条。

2 个答案:

答案 0 :(得分:2)

通过使用像row_number()这样的窗口函数,有多种方法可以获得您想要的方法。 row_number函数允许您使用分区为每行创建唯一编号,在您的情况下,分区由dh_type创建,然后由dh_createDT命令创建该编号。最后的结果将是row_number = 1的行。:

select dh_type, 
      dh_product
from
(
  SELECT 
      dh_type, 
      dh_product,
      rn = row_number() over(partition by dh_type order by dh_createDT desc)
  FROM myProducts
  WHERE dh_productid = '08-BLD4011603S0'
      AND dh_type IN ('New','Old','Ref')
) d
where rn = 1;

获得结果的另一种方法是使用一个子查询,为每个max(dh_createDT)dh_type获取dh_product,然后将其加入到您的表中:

select 
  dh_type,
  dh_product
from myProducts p
inner join
(
  select 
    dh_type, 
    dh_product,
    MaxDate = max(dh_createDT)
  from myProducts
  where h_productid = '08-BLD4011603S0'
    and dh_type IN ('New','Old','Ref') 
  group by dh_type, dh_product
) p1
  on p.dh_type = p1.dh_type
  and p.dh_product = p1.dh_product
  and p.dh_createDT = p1.MaxDate
where p.h_productid = '08-BLD4011603S0'
  and p.dh_type IN ('New','Old','Ref') 

答案 1 :(得分:1)

奥利有一个非常好的答案。但是,如果性能问题,那么以下内容可能会更快:

(SELECT TOP (1) dh_type, dh_product
 FROM myProducts
 WHERE dh_productid = '08-BLD4011603S0' AND dh_type = 'New'
 ORDER BY dh_createDt DESC
) UNION ALL
(SELECT TOP (1) dh_type, dh_product
 FROM myProducts
 WHERE dh_productid = '08-BLD4011603S0' AND dh_type = 'Old'
 ORDER BY dh_createDt DESC
) UNION ALL
(SELECT TOP (1) dh_type, dh_product
 FROM myProducts
 WHERE dh_productid = '08-BLD4011603S0' AND dh_type = 'Ref'
 ORDER BY dh_createDt DESC
);

对于性能,您需要myProducts(dh_productid, dh_type, dh_createDt)上的索引。您也可以在dh_product中完成,因此索引完全涵盖了查询。