繁体   English   中英

在同一张表上使用INNER JOIN的多个嵌套SELECT DISTINCT语句

[英]Multiple nested SELECT DISTINCTstatments using INNER JOIN on the same table

我一直试图编写一个查询,以通过发布日期并忽略其余行来仅选择表中每个'Item No_'中的最新条目。 我一直在遇到各种错误。 最后一个令人烦恼,因为我现在看不到错误。 这是查询的代码段:

SELECT ri.* 
FROM [Rigid Industries$Item Ledger Entry] ri 
INNER JOIN 
  (SELECT DISTINCT [Item No_], MAX([Posting Date]) AS maxDate 
    FROM [Rigid Industries$Item Ledger Entry] 
    WHERE maxDate <= CONVERT(datetime, '2014-01-17 02:33:16.939') 
    GROUP BY maxDate, [Item No_]] 
  ) itDat 
  ON ri.[Item No_] = itDat.[Item No_] 
WHERE ri.[Quantity] > 0 
ORDER BY ri.[Location Code] DESC, ri.[Item No_] ASC, ri.[Posting Date] DESC;

在Peter G和rs的帮助下,我找到了解决方案。

SELECT E.*
FROM [Rigid Industries\$Item Ledger Entry] E
WHERE [Posting Date] = 
    (SELECT MAX(x.[Posting Date])
    FROM [Rigid Industries\$Item Ledger Entry] x 
    WHERE x.[Item No_] = E.[Item No_] 
    AND x.[Posting Date] <= CONVERT(datetime, '$dateYo')
    ) AND
    [Entry No_] = 
    (SELECT MAX(y.[Entry No_])
    FROM [Rigid Industries\$Item Ledger Entry] y
    WHERE y.[Item No_] = E.[Item No_] 
    )
AND E.[Quantity] > 0 
ORDER BY E.[Location Code] DESC, E.[Item No_] ASC, E.[Posting Date] DESC;

您可以将查询重写为此

SELECT E.*
    FROM [Rigid Industries$Item Ledger Entry] E
    WHERE [Posting Date] = (SELECT MAX(x.[Posting Date]) FROM 
                            FROM [Rigid Industries$Item Ledger Entry] x  
                            WHERE x.[Item No_] = E.[Item No_] AND 
                x.[Posting Date] <= CONVERT(datetime, '2014-01-17 02:33:16.939'))
AND E.[Quantity] > 0 
ORDER BY E.[Location Code] DESC, E.[Item No_] ASC, E.[Posting Date] DESC;

您有几个问题。 一种语法错误是内部查询通过maxdate聚合,然后还有其他查询。 那是没有必要的。 逻辑问题是您需要在on子句中使用日期:

SELECT ri.* 
FROM [Rigid Industries$Item Ledger Entry] ri INNER JOIN 
     (SELECT [Item No_], MAX([Posting Date]) AS maxDate 
      FROM [Rigid Industries$Item Ledger Entry] 
      WHERE [Posting Date] <= CONVERT(datetime, '2014-01-17 02:33:16.939') 
      GROUP BY [Item No_]] 
     ) itDat 
     ON ri.[Item No_] = itDat.[Item No_] and
        ri.[Posting Date] = itDat.maxDate
WHERE ri.[Quantity] > 0 
ORDER BY ri.[Location Code] DESC, ri.[Item No_] ASC, ri.[Posting Date] DESC;

编写此类查询的另一种方法是使用not exists子句以及[Rigid Industries$Item Ledger Entry]([Item No_], [Posting Date])上的索引:

SELECT ri.* 
FROM [Rigid Industries$Item Ledger Entry] ri 
WHERE ri.[Quantity] > 0 AND
      NOT EXISTS (SELECT 1
                  FROM [Rigid Industries$Item Ledger Entry] ri2
                  WHERE ri2.[Item No_] = ri.[Item No_] AND
                        ri2.[Posting Date] > ri.[Posting Date]
                 )
ORDER BY ri.[Location Code] DESC, ri.[Item No_] ASC, ri.[Posting Date] DESC;

这就是说:“让我从该表中获得所有行,且名称太长且太复杂,以使该表中没有其他行具有相同的项目编号和更长的发布日期。”

[Rigid Industries$Item Ledger Entry]是否具有主键或唯一索引? 没有一个,这可能仍然会给您带来重复,但是仍然会有所改进:

SELECT ri.* 
FROM [Rigid Industries$Item Ledger Entry] ri 
INNER JOIN 
  (SELECT [Item No_], MAX([Posting Date]) AS maxDate 
    FROM [Rigid Industries$Item Ledger Entry] 
    WHERE [Posting Date] <= CONVERT(datetime, '2014-01-17 02:33:16.939') 
    GROUP BY [Item No_] 
  ) itDat 
  ON ri.[Item No_] = itDat.[Item No_]
 AND ri.[Posting Date] = itDat.maxDate
WHERE ri.[Quantity] > 0 
ORDER BY ri.[Location Code] DESC, ri.[Item No_] ASC, ri.[Posting Date] DESC;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM