我正在使用SQL Server 2012.
我需要生成一个输出,其中包含多个" top"的结果。查询,其中#of" top"每个查询中返回的行因另一个表中的值而异。
我的第一个表格,称之为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以升序返回Table2中的那么多顶行。因此,例如,因为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中带回多个值,而我无法弄清楚如何将其运行到"运行&# 34;对于每个MARKET / MEASURE组合。
非常感谢。
答案 0 :(得分:2)
这是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
答案 1 :(得分:1)
对于处于同样困境的任何人,我想出了另一种完成同样事情的方法,使用ROW_NUMBER()窗口函数而不是尝试动态使用TOP。我们的想法是在Table2中添加一个行号,按市场划分。测量并按姓氏排序,然后将Table1.Number连接到Table2,并仅选择行号小于Table1.Number的行,从而返回" top"根据Table1.Number。
的行数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