繁体   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