MIN CO

时间:2017-08-29 20:00:44

标签: sql

我正在通过我们的ERP系统设定采购订单的时间交货跟踪。我在该系统中使用三个不同的表当我们的接收部门输入日期时,我可以将其与截止日期进行比较 - 问题是,我们的会计有时会想要调整信息然后导致另一个(或多个)条目该表和一个简单的计数查询将包括那些日期 - 从而提供不良信息。

我的查询是:

 SELECT        COUNT(PO_Receipts.ORDNUM_55) AS OrderCount
             , SUM(CASE WHEN TNXDTE_55 = CURDUE_10 THEN 1
                   ELSE 0 END) AS On_Time
             , SUM(CASE WHEN TNXDTE_55 < CURDUE_10 THEN 1
                   ELSE 0 END) AS Early
             , SUM(CASE WHEN TNXDTE_55 > CURDUE_10 THEN 1
                   ELSE 0 END) AS Pastdue
 FROM          PO_Receipts
               INNER JOIN Order_Master
                 ON PO_Receipts.TYPE_55 = Order_Master.TYPE_10 
                 AND PO_Receipts.ORDNUM_55 = Order_Master.ORDNUM_10 
                 AND PO_Receipts.LINNUM_55 = Order_Master.LINNUM_10
                 AND PO_Receipts.DELNUM_55 = Order_Master.DELNUM_10 
                 AND PO_Receipts.PRTNUM_55 = Order_Master.PRTNUM_10
               INNER JOIN Part_Master
                 ON Order_Master.PRTNUM_10 = Part_Master.PRTNUM_01
WHERE          (Order_Master.TYPE_10 <> 'NI') 
               AND (PO_Receipts.TNXDTE_55 >= 
                    DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0))
               AND (PO_Receipts.TNXDTE_55 < 
                    DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0))
               AND (Part_Master.INSRQD_01 = 'Y') 

以下是返回数据的一个示例(删除COUNT和别名,以便我可以看到正在计算的内容)

ORDNUM_55 |LINNUM_55| DELNUM_55| TNXDTE_55 | PRTNUM_55| CURDUE_10 | 
:---------|:--------|:---------|:----------|:---------|:----------|
70029239    01       01          8/18/2017  CBL1592    8/18/2017
70029239    01       01          8/18/2017  CBL1592    8/18/2017 
70029239    02       01          8/18/2017  CBL1593    8/18/2017 
70029239    02       01          8/18/2017  CBL1593    8/18/2017 
70029239    02       02          8/15/2017  CBL1593    8/18/2017 
70029239    02       02          8/15/2017  CBL1593    8/18/2017 
70029239    02       02          8/17/2017  CBL1593    8/18/2017 
70029239    02       02          8/17/2017  CBL1593    8/18/2017 

这就是我想要的(再次,为了清晰起见,删除了COUNT个)

ORDNUM_55 |LINNUM_55| DELNUM_55| TNXDTE_55 | PRTNUM_55| CURDUE_10 | 
:---------|:--------|:---------|:----------|:---------|:----------|
70029239    01       01          8/18/2017  CBL1592    8/18/2017
70029239    02       02          8/15/2017  CBL1593    8/18/2017 

我假设我会使用MIN(TNXDTE_55),但我不知道如何在COUNT语句中 在此先感谢您的帮助

1 个答案:

答案 0 :(得分:2)

根据示例输出,我了解您需要获取具有不同PRTNUM_55值的给定ORDNUM_55的行,如果给定PRTNUM_55的那一行多一行,则需要获取具有最小日期的行。此外,您似乎正在使用SQL Server,因为您使用的是getdate()和datediff()。

在这种情况下,您可以使用EXISTS / NOT EXISTS

SELECT PO_Receipts.ORDNUM_55,PO_Receipts.LINNUM_55, 
       PO_Receipts.DELNUM_55, PO_Receipts.TNXDTE_55, 
       PO_Receipts.PRTNUM_55, Order_Master.CURDUE_10
FROM PO_Receipts 
INNER JOIN Order_Master
   ON PO_Receipts.ORDNUM_55 = Order_Master.ORDNUM_10
WHERE (PO_Receipts.ORDNUM_55 = '70029239')
  AND (Order_Master.DUEQTY_10 = 0)
  AND (PO_Receipts.TNXQTY_55 > 0)
  AND NOT EXISTS (SELECT * FROM PO_Receipts AS ReceiptsTemp
      -- conditions for joining the rows
      WHERE ReceiptsTemp.ORDNUM_55=PO_Receipts.ORDNUM_55
        AND ReceiptsTemp.PRTNUM_55=PO_Receipts.PRTNUM_55
      -- conditions for the filter logic
        AND ReceiptsTemp.TNXDTE_55<PO_Receipts.TNXDTE_55)

这将搜索具有相同ORDNUM和PRTNUM的行,并仅返回具有最小日期的行,但请注意,如果同一ORDNUM / PRTNUM中的两行或多行具有最小日期,则它将返回所有行。< / p>

如果每个ORDNUM / PRTNUM只需要一行,则需要根据数据的性质执行一个或多个额外步骤:

  1. 添加其他条件,例如,当最小日期相同时返回具有最小DELNUM的行(请注意,如果要使用字段,可以在EXISTS子查询中使用INNER JOIN Order_Master用于额外过滤):

    AND NOT EXISTS (SELECT * FROM PO_Receipts AS ReceiptsTemp
      -- conditions for joining the rows
      WHERE ReceiptsTemp.ORDNUM_55=PO_Receipts.ORDNUM_55
        AND ReceiptsTemp.PRTNUM_55=PO_Receipts.PRTNUM_55
      -- conditions for what you want
        AND (ReceiptsTemp.TNXDTE_55<PO_Receipts.TNXDTE_55
             OR (ReceiptsTemp.TNXDTE_55=PO_Receipts.TNXDTE_55
                 AND ReceiptsTemp.DELNUM_55<PO_Receipts.DELNUM_55)))
    
  2. 使用(SELECT DISTINCT ...) AS Subquery删除完全相同的副本,然后使用子查询的结果进行分组:

    SELECT COUNT(PO_Receipts.ORDNUM_55) AS OrderCount, <other aggregates>
    FROM (
      SELECT PO_Receipts.ORDNUM_55,PO_Receipts.LINNUM_55, 
             PO_Receipts.DELNUM_55, PO_Receipts.TNXDTE_55, 
             PO_Receipts.PRTNUM_55, Order_Master.CURDUE_10
      FROM PO_Receipts 
      INNER JOIN Order_Master
         ON PO_Receipts.ORDNUM_55 = Order_Master.ORDNUM_10
      WHERE (PO_Receipts.ORDNUM_55 = '70029239')
        AND (Order_Master.DUEQTY_10 = 0)
        AND (PO_Receipts.TNXQTY_55 > 0)
        AND NOT EXISTS (SELECT * FROM PO_Receipts AS ReceiptsTemp
            -- conditions for joining the rows
            WHERE ReceiptsTemp.ORDNUM_55=PO_Receipts.ORDNUM_55
              AND ReceiptsTemp.PRTNUM_55=PO_Receipts.PRTNUM_55
            -- conditions for the filter logic
              AND (ReceiptsTemp.TNXDTE_55<PO_Receipts.TNXDTE_55
                   OR (ReceiptsTemp.TNXDTE_55=PO_Receipts.TNXDTE_55
                       AND ReceiptsTemp.DELNUM_55<PO_Receipts.DELNUM_55)))
    ) AS DistinctRows
    GROUP BY <group condition>