복붙노트

[SQL] 같은 테이블의 SQL 서버에서 행에 해당하는 선택

SQL

같은 테이블의 SQL 서버에서 행에 해당하는 선택

나는 다른 열을 기준으로 약간의 열을 얻으려면

예 테이블 :

| BlilCode | BlilShortName | BatchWeigth | BillVersion | BlilMaxTime |
+----------+---------------+-------------+-------------+-------------+
| 5502     | aaa           | 1.00        | 1           | 360         |
| 5502     | aaa           | 2.00        | 2           | 240         |
| 5510     | bbb           | -32.94      | 2           | 360         |
| 5510     | bbb           | 1.00        | 1           | 360         |
| 5510     | bbb           | 36.37       | 3           | 3600        |

모든 BlilCode이 최대이기하지만 난 BillVersion가 최대 인 행을 얻으려면

예상 결과

| BlilCode | BlilShortName | BatchWeigth | BillVersion | BlilMaxTime |
+----------+---------------+-------------+-------------+-------------+
| 5502     | aaa           | 2.00        | 2           | 240         |
| 5510     | bbb           | 36.37       | 3           | 3600        |

나의 현재 쿼리는 다음과 같습니다

SELECT    
    [BlilCode], [BlilShortName], 
    BatchWeigth, (BillVersion) AS BillVersion, [BlilMaxTime]
FROM 
    [CVfeedDB].[dbo].[constants.Blil]  
WHERE 
    BlilActive = 1 AND BatchWeigth IS NOT NULL
ORDER BY 
    BlilCode

해결법

  1. ==============================

    1.난 정말 당신의 설명에서 스마트하고 있지 않다, 그러나, 결과는 다음 쿼리를 사용하여 달성 될 수있다

    난 정말 당신의 설명에서 스마트하고 있지 않다, 그러나, 결과는 다음 쿼리를 사용하여 달성 될 수있다

    select your_table.*
    from your_table 
    join
    (
      select BlilShortName, max(billversion) bmax
      from your_table
      group by BlilShortName
    ) t on your_table.billversion = t.bmax and your_table.BlilShortName = t.BlilShortName
    

    항상 순차 검색을 사용 ROW_NUMBER 솔루션과 비교했을 때 내 경험에서 더 빨리 어떤 경우에는 될 수 있습니다.

    성과급

    효율성에 관한 논의가 있기 때문에 나는 간단한 테스트를 추가 감히

    IF OBJECT_ID('dbo.GTable', 'U') IS NOT NULL  DROP TABLE dbo.GTable
    SELECT TOP 1000000
          NEWID() id, 
          ABS(CHECKSUM(NEWID())) % 100 group_id, 
          ABS(CHECKSUM(NEWID())) % 10000 orderby
     INTO GTable
    FROM    sys.sysobjects
    CROSS JOIN sys.all_columns
    
    SET STATISTICS TIME on
    -- GROUP BY version
    select t1.*
    from gtable t1
    join
        (
          SELECT group_id, max(orderby) gmax
          from gtable
          group by group_id
        ) t2 on t1.group_id = t2.group_id and t1.orderby = t2.gmax
    
    -- WINDOW FUNCTION version
    select t.id, t.group_id, t.orderby
    from
    (
    select *, 
           dense_rank() over (partition by group_id order by orderby desc) rn
    from gtable 
    ) t
    where t.rn = 1
    

    내 서버에서이를 실행하면 다음 GROUP BY 버전의 성능이 두 배 더 윈도우 함수 버전보다 이상입니다. 또한, 나는 인덱스를 작성하는 경우

    CREATE NONCLUSTERED INDEX ix_gtable_groupid_orderby
        ON [dbo].[GTable] (group_id,orderby) INCLUDE (id)
    

    이 인덱스에도 불구하고 연속 스캔을 사용하기 때문에 윈도우 함수 솔루션의 성능은 동일한 반면, 그 성능은 더욱 세 번보다 나은입니다.

  2. ==============================

    2.당신의 결과는 당신이 원하는 것을 제안 :

    당신의 결과는 당신이 원하는 것을 제안 :

    select db.*
    from (select db.*,
                 row_number() over (partition by shortname order by billversion desc) as seqnum
          from db
         ) db
    where seqnum = 1;
    

    당신이 blilcode에 기반한다면, 결과는 대신에 두 세 개의 행이있을 것입니다.

    참고 : 해당 쿼리가 될 수 있도록 문제는,이 후 편집 한 :

    select db.*
    from (select db.*,
                 row_number() over (partition by blilcode order by billversion desc) as seqnum
          from db
         ) db
    where seqnum = 1;
    
  3. from https://stackoverflow.com/questions/47674876/select-corresponding-to-row-from-the-same-table-sql-server by cc-by-sa and MIT license