programing

SQL Server: MAX(DATE) 행만 선택

powerit 2023. 4. 23. 11:35
반응형

SQL Server: MAX(DATE) 행만 선택

데이터 테이블이 있습니다(DB는 MSQL).

ID  OrderNO  PartCode  Quantity DateEntered
417 2144     44917     100      18-08-11
418 7235     11762     5        18-08-11
419 9999     60657     100      18-08-11
420 9999     60657     90       19-08-11

OrderNO, PartCode, Quantity를 마지막으로 등록된 주문에 대해서만 반품하는 쿼리를 하고 싶습니다.

예시표에서 다음 정보를 얻고 싶습니다.

 OrderNO  PartCode  Quantity     
 2144     44917     100      
 7235     11762     5        
 9999     60657     90  

주문 9999에 대해 반환된 행은 1개뿐입니다.

감사합니다!

한다면rownumber() over(...)이용하실 수 있습니다.

select OrderNO,
       PartCode,
       Quantity
from (select OrderNO,
             PartCode,
             Quantity,
             row_number() over(partition by OrderNO order by DateEntered desc) as rn
      from YourTable) as T
where rn = 1      

가장 좋은 방법은 미카엘 에릭슨이야ROW_NUMBER()를 사용할 수 있습니다.

다음으로 Cularis의 답변에 따라 쿼리에 참여하는 것이 최선입니다.

또는 가장 간단하고 직접적인 방법은 WHERE 절의 상관 서브쿼리입니다.

SELECT
  *
FROM
  yourTable AS [data]
WHERE
  DateEntered = (SELECT MAX(DateEntered) FROM yourTable WHERE orderNo = [data].orderNo)

아니면...

WHERE
  ID = (SELECT TOP 1 ID FROM yourTable WHERE orderNo = [data].orderNo ORDER BY DateEntered DESC)
select OrderNo,PartCode,Quantity
from dbo.Test t1
WHERE EXISTS(SELECT 1
         FROM dbo.Test t2
         WHERE t2.OrderNo = t1.OrderNo
           AND t2.PartCode = t1.PartCode
         GROUP BY t2.OrderNo,
                  t2.PartCode
         HAVING t1.DateEntered = MAX(t2.DateEntered))

이것은 위에서 제공한 모든 쿼리 중 가장 빠른 쿼리입니다.조회비용은 0.0070668입니다.

위의 Mikael Eriksson에 의한 바람직한 답변은 0.0146625의 쿼리 비용을 가집니다.

이렇게 작은 샘플의 성능은 신경 쓰지 않을 수 있지만, 큰 쿼리의 경우 모두 합산됩니다.

SELECT t1.OrderNo, t1.PartCode, t1.Quantity
FROM table AS t1
INNER JOIN (SELECT OrderNo, MAX(DateEntered) AS MaxDate
            FROM table
            GROUP BY OrderNo) AS t2
ON (t1.OrderNo = t2.OrderNo AND t1.DateEntered = t2.MaxDate)

내부 쿼리는 다음을 모두 선택합니다.OrderNo최대 날짜로요테이블의 다른 열을 가져오려면 다음 위치에 결합하십시오.OrderNo및 그MaxDate.

인덱스 ID와 OrderNo를 가지고 있는 경우 IN을 사용할 수 있습니다. (단, 몇 가지 사이클을 절약하기 위해 단순함을 무명으로 바꾸는 것은 싫습니다.)

select * from myTab where ID in(select max(ID) from myTab group by OrderNo);

또한 select 문을 왼쪽 조인 쿼리로 사용할 수도 있습니다.예:

... left join (select OrderNO,
   PartCode,
   Quantity from (select OrderNO,
         PartCode,
         Quantity,
         row_number() over(partition by OrderNO order by DateEntered desc) as rn
  from YourTable) as T where rn = 1 ) RESULT on ....

이것을 검색하는 사람에게 도움이 되었으면 합니다.

MySql의 경우 다음과 같은 작업을 수행할 수 있습니다.

select OrderNO, PartCode, Quantity from table a
join (select ID, MAX(DateEntered) from table group by OrderNO) b on a.ID = b.ID

rownumber() over(...)는 동작하고 있습니다만, 2가지 이유로 이 솔루션이 마음에 들지 않았습니다.- 이 함수는 SQL2000과 같은 이전 버전의 SQL을 사용하는 경우 사용할 수 없으며, 실제로 읽을 수 없습니다.

또 다른 솔루션은 다음과 같습니다.

SELECT tmpall.[OrderNO] ,
       tmpall.[PartCode] ,
       tmpall.[Quantity] ,
FROM   (SELECT [OrderNO],
               [PartCode],
               [Quantity],
               [DateEntered]
        FROM   you_table) AS tmpall
       INNER JOIN (SELECT [OrderNO],
                          Max([DateEntered]) AS _max_date
                   FROM   your_table
                   GROUP  BY OrderNO ) AS tmplast
               ON tmpall.[OrderNO] = tmplast.[OrderNO]
                  AND tmpall.[DateEntered] = tmplast._max_date

이것은 나에게 완벽하게 잘 작동했다.

    select name, orderno from (
         select name, orderno, row_number() over(partition by 
           orderno order by created_date desc) as rn from orders
    ) O where rn =1;

JOIN을 사용하지 않도록 합니다.

SELECT SQL_CALC_FOUND_ROWS *  FROM (SELECT  msisdn, callid, Change_color, play_file_name, date_played FROM insert_log
   WHERE play_file_name NOT IN('Prompt1','Conclusion_Prompt_1','silent')
 ORDER BY callid ASC) t1 JOIN (SELECT MAX(date_played) AS date_played FROM insert_log GROUP BY callid) t2 ON t1.date_played=t2.date_played

Mikael Eriksson의 답변에 덧붙이자면, 같은 날짜의 중복(OrderNO, PartCode) 행이 있는 경우, 이것을 사용하는 방법에 미묘한 차이가 있습니다.다음을 사용할 수 있습니다.

  1. row_number()는 중복된 행을 삭제하고 행 하나만 반환합니다.
  2. rank()는 중복된 행을 모두 반환합니다.

알고 보니 row_number가 아니라 순위가 필요했어요.

select OrderNO,
       PartCode,
       Quantity
from (select OrderNO,
             PartCode,
             Quantity,
             row_number() over(partition by OrderNO order by DateEntered desc) as rn
      from YourTable) as T
where rn = 1 

난 이거면 돼.MAX(CONVERT(날짜, ReportDate))사용하여 날짜 값이 있는지 확인합니다.

select max( CONVERT(date, ReportDate)) FROM [TraxHistory]

언급URL : https://stackoverflow.com/questions/7118170/sql-server-select-only-the-rows-with-maxdate

반응형