子过滤SQL查询

时间:2014-05-08 10:15:21

标签: sql sql-server

我正在使用Microsoft SQL Server Management Studio并希望对我的SQL查询进行子过滤。我认为一个例子是最好的。以下是样本数据。考虑facodeDateStartstockQty列。我想每个唯一facode只返回一行。这应该基于最新的DateStart值。返回的stockQty值应该是与DateStart链接的值。

非常感谢任何帮助。谢谢!

这是我当前的查询返回的内容:

artcode   | warehouse  |  facode | DateStart   | stockQty

 30003    | SM01       |  11111  | 4/5/2014    | 445
 30003    | SM01       |  11111  | 4/21/2014   | 1002
 30003    | SM01       |  11111  | 5/1/2014    | 385
 30003    | SM01       |  22222  | 3/23/2014   | 200
 30003    | SM01       |  22222  | 4/28/2014   | 350
 30003    | SM01       |  22222  | 4/29/2014   | 400
 30003    | SM01       |  33333  | 4/22/2014   | 125
 30003    | SM01       |  33333  | 5/3/2014    | 75   
 30003    | SM01       |  33333  | 5/5/2014    | 300

以下是我希望查询返回的内容:

artcode   | warehouse|  facode |  DateStart  | stockQty

 30003    | SM01     |  11111  | 5/1/2014    | 385
 30003    | SM01     |  22222  | 4/29/2014   | 400 
 30003    | SM01     |  33333  | 5/5/2014    | 300

以下是我的代码:

    SELECT gbkmut.artcode
     , gbkmut.warehouse
     , gbkmut.facode
     , ItemNumbers.DateStart
     , ROUND(SUM(aantal),2) as stockQty
  FROM gbkmut
 INNER JOIN 
       ItemNumbers 
    ON gbkmut.artcode=Itemnumbers.Itemcode
 INNER JOIN Items as ic 
    ON ItemNumbers.ItemCode=ic.ItemCode
 INNER JOIN Items 
    on Items.GLAccountDistribution = gbkmut.reknr 
   AND gbkmut.artcode =Items.ItemCode 
   and items.type ='S' 
 WHERE gbkmut.transtype IN  ('X', 'N', 'C', 'P') 
   AND gbkmut.remindercount <> 999 
   AND artcode='30T30003'
 GROUP BY 
       gbkmut.warehouse
     , facode, artcode
     , items.costpricestandard
     , items.itemcode
     , itemnumbers.datestart
HAVING ROUND(SUM(aantal),2)>0.1
 ORDER BY 
       artcode
     , facode
     , gbkmut.warehouse

3 个答案:

答案 0 :(得分:1)

您可以使用row_number()

select * 
from 
(
    select *, 
    row_number() over (partition by artcode,warehouse , facode order by datestart desc) rn
    from 
    (
       -- your current query here
    ) src
) v
where rn = 1

请参阅http://technet.microsoft.com/en-us/library/ms186734.aspx

答案 1 :(得分:0)

row_number()是一种方法。另一种选择是使用CROSS APPLY,这就像是对相关子查询的连接。您可以编写一个子查询来返回单个artcodefacode所需的数据 - 这样您就可以使用TOP (1)获取具有最新日期的行 - 然后使用{{1将它连接到gbkmut并为每个相关行提供结果。类似的东西:

CROSS APPLY

This page详细介绍了SELECT gbkmut.artcode, gbkmut.warehouse, gbkmut.facode, x.DateStart, x.stockQty FROM gbkmut CROSS APPLY ( select top (1) g.facode, ItemNumbers.DateStart, ROUND(SUM(aantal),2) as stockQty from gbkmut g inner join ItemNumbers ON g.artcode=Itemnumbers.Itemcode INNER JOIN Items as ic ON ItemNumbers.ItemCode=ic.ItemCode INNER JOIN Items on Items.GLAccountDistribution = g.reknr AND g.artcode =Items.ItemCode and items.type ='S' WHERE g.transtype IN ('X', 'N', 'C', 'P') AND g.remindercount <> 999 AND artcode='30T30003' AND g.facode = gbkmut.facode AND gbkmut.artcode = g.artcode GROUP BY g.warehouse, g.facode, g.artcode HAVING ROUND(SUM(aantal),2)>0.1 ORDER BY ItemNumbers.DateStart DESC ) x ORDER BY artcode, facode, gbkmut.warehouse ,还讨论了APPLYAPPLY的效果。两个选项中哪一个表现更好(照例!)取决于您的数据。

答案 2 :(得分:0)

使用CTE可以使podiluska(+1)的查询更具可读性

With Ord AS (
  Select artcode
       , warehouse
       , facode
       , DateStart
       , stockQty
       , Last = Row_Number() OVER (PARTITION BY artcode, warehouse, facode
                                   ORDER BY DateStart Desc)
  FROM   gbkmut
)
SELECT artcode
     , warehouse
     , facode
     , DateStart
     , stockQty
FROM   Ord
Where  Last = 1

SQLFiddle演示