簡體   English   中英

SQL生成一個包含多個前X個記錄的表,其中top#來自另一個表

[英]SQL Generate a table of multiple top X records, where top # comes from another table

我正在使用SQL Server 2012。

我需要生成一個輸出,其中包含多個“頂部”查詢的結果,其中每個查詢中返回的“頂部”行的數量根據另一個表中的值而變化。

我的第一個表格,稱為Table1,是參考表格,其中NUMBER告訴我每個獨特的市場/度量需要從另一個表格中返回多少頂行。

MARKET      MEASURE     NUMBER
------      -------      ------
MarketA     MeasureA    411
MarketA     MeasureB    396
MarketB     MeasureA    548
MarketB     MeasureC    424
MarketC     MeasureC    411

第二個表Table2列出了給定MARKET / MEASURE中每個人的詳細信息,其中MARKET和MEASURE的組合是我的主要關鍵。 任何給定的市場/措施都有許多條目。

MARKET      MEASURE      LASTNAME      COMPLIANT
------      -------      --------      ---------
MarketA     MeasureA     Coppola       Y
MarketA     MeasureA     Winterbottom  N
MarketA     MeasureB     Scorsese      Y
MarketC     MeasureC     Tarr          Y

對於Table1中的每個值,我需要根據一種LASTNAME以升序返回表2中的那么多頂行。 因此,例如,因為Table1對於MarketA / MeasureA的NUMBER為411,我的輸出需要包含Table2中的TOP 411 *行(基於該市場中按LASTNAME升序排序的所有人),以及MarketA /的TOP 396行MeasureB,然后是MarketB / MeasureA的TOP 548行,依此類推,全部在一個表中,好像我已經單獨“UNIONed”(?)每個查詢。

如何動態執行此操作而不必對表1中的每個MARKET / MEASURE進行UNION個別查詢(其中超過1000個)?

我覺得答案是使用select表達式在TOP表達式中生成#,就像......

select TOP (select NUMBER from TABLE2) *  
from TABLE1 t1
inner join TABLE2 t2 on t2.MARKET = T1.MARKET
                     and t2.MEASURE = T2.MEASURE 

...但顯然我錯過了幾個步驟,因為TOP表達式將從TABLE2中帶回多個值,而我無法弄清楚如何讓它為每個MARKET / MEASURE組合“運行”。

非常感謝。

這就是APPLY可以用來做的事情

SELECT
    *

FROM
    Table1
    CROSS APPLY
    (
        SELECT TOP (Table1.Number)
            *

        FROM
            Table2

        WHERE
            Table1.Market = Table2.Market
            AND Table1.Measure = Table2.Measure

        ORDER BY
            LastName
    ) AS TopResults

http://sqlfiddle.com/#!6/46b57/4

對於處於同樣困境的任何人,我想出了另一種完成同樣事情的方法,使用ROW_NUMBER()窗口函數而不是嘗試動態使用TOP。 想法是向Table2添加一個行號,按市場和度量分區並按姓氏排序,然后將Table1.Number加入Table2,並僅選擇行號小於Table1.Number的行,從而返回根據Table1.Number的“top”行數。

with temp as (select 'rownum' = row_number() over(partition by t2.market, t2.measure)
                                                  order by t2.lastname)
                , t2.*
                , t1.number
              from table2 t2
              inner join table1 t1 on t1.market = t2.market
                                   and t1.measure = t2.measure)
select *
from temp
where rownum <= number
order by market, measure, rownum

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM