문제

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. 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.

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. That is unnecessary. The logical problem is that you need to use the date in the on clause:

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]):

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? 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 ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top