简体   繁体   English

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

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

I have been trying to write a query to select only the most recent of every 'Item No_' in the table by posting date and ignoring the rest of the rows. 我一直试图编写一个查询,以通过发布日期并忽略其余行来仅选择表中每个'Item No_'中的最新条目。 I have been getting various errors. 我一直在遇到各种错误。 The last of which is an annoyance as I cannot see the error at this point. 最后一个令人烦恼,因为我现在看不到错误。 Here is a snippet of the query: 这是查询的代码段:

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;

With the help of Peter G and rs, I came to a solution. 在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;

you can rewrite your query to this 您可以将查询重写为此

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;

Your have a couple of problems. 您有几个问题。 One syntax error is that the inner query is aggregating by maxdate , and then there are others. 一种语法错误是内部查询通过maxdate聚合,然后还有其他查询。 That is unnecessary. 那是没有必要的。 The logical problem is that you need to use the date in the on clause: 逻辑问题是您需要在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;

An alternative way of writing this type of query is to use a not exists clause along with an index on [Rigid Industries$Item Ledger Entry]([Item No_], [Posting Date]) : 编写此类查询的另一种方法是使用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;

What this is saying is: "Get me all the rows from that table with the too long and complicated name such that there are no other rows in the table with the same item number and a bigger posting date." 这就是说:“让我从该表中获得所有行,且名称太长且太复杂,以使该表中没有其他行具有相同的项目编号和更长的发布日期。”

Does [Rigid Industries$Item Ledger Entry] have a primary key or unique index? [Rigid Industries$Item Ledger Entry]是否具有主键或唯一索引? Without one, this might still give you duplicates but will still be an improvement: 没有一个,这可能仍然会给您带来重复,但是仍然会有所改进:

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