SQL Server:按给定因子多次选择一行

时间:2014-11-07 17:16:06

标签: sql sql-server

我想从表中选择,但问题是,我有一个因子列,表示必须选择此行的次数(这是一个仅用于演示的示例表):

ID        Factor         Count
-------------------------------
1            1             235        
2            2             345        
3            2             214        
4            3             95        
5            1             135        
6            1             750  

查询:

select top 6 
   [id], [count] 
from 
   table
order by 
    id                  --somewhere in here I must take factor into consideration

结果必须是:

ID            Count
---------------------
 1            235                    
 2            345                    
 2            345                    
 3            214                    
 3            214                    
 4            135        

4 个答案:

答案 0 :(得分:7)

这应该足够了:

SELECT A.*
FROM dbo.YourTable A
INNER JOIN (SELECT *
            FROM master.dbo.spt_values
            WHERE type = 'P') B
    ON A.Factor >= B.number+1

Here is a sqfiddle及其演示。

结果是:

╔════╦════════╦═══════╗
║ ID ║ Factor ║ Count ║
╠════╬════════╬═══════╣
║  1 ║      1 ║   235 ║
║  2 ║      2 ║   345 ║
║  2 ║      2 ║   345 ║
║  3 ║      2 ║   214 ║
║  3 ║      2 ║   214 ║
║  4 ║      3 ║    95 ║
║  4 ║      3 ║    95 ║
║  4 ║      3 ║    95 ║
║  5 ║      1 ║   135 ║
║  6 ║      1 ║   750 ║
╚════╩════════╩═══════╝

如果factor列可能大于2048,那么您可以使用数字表。

答案 1 :(得分:0)

如果您知道“最大”因素是什么。

SELECT [id],[count] 
FROM table
WHERE factor > 1

UNION ALL

SELECT [id],[count] 
FROM table
WHERE factor > 2

UNION ALL

SELECT [id],[count] 
FROM table
WHERE factor > 3

.
.
.

order by [id]

使用递归CTE可能有办法做到这一点。不知道你想付出多少努力。

答案 2 :(得分:0)

这是使用“tally”a.k.a。“数字”表的一个很好的候选者,它只是一个包含增量整数列表的表。

以下是使用公用表表达式(CTE)动态创建“计数”表的示例。

WITH lv0 AS (SELECT 0 g UNION ALL SELECT 0)
    ,lv1 AS (SELECT 0 g FROM lv0 a CROSS JOIN lv0 b) -- 4
    ,lv2 AS (SELECT 0 g FROM lv1 a CROSS JOIN lv1 b) -- 16
    ,lv3 AS (SELECT 0 g FROM lv2 a CROSS JOIN lv2 b) -- 256
    ,lv4 AS (SELECT 0 g FROM lv3 a CROSS JOIN lv3 b) -- 65,536
    ,lv5 AS (SELECT 0 g FROM lv4 a CROSS JOIN lv4 b) -- 4,294,967,296
    ,Tally (n) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM lv5)
SELECT TOP 6 t.[id], t.[count]
FROM table t
INNER JOIN Tally n on n.n <= t.factor
ORDER BY t.[id]

或者,如果“因素”可能很大,或者您使用上面的查询遇到性能问题,那么您可能希望为计数表创建物理表而不是使用CTE。

答案 3 :(得分:0)

这是我用CTE做的方法。

;WITH cte
     AS (SELECT id,Factor,count
         FROM   tablename
         UNION ALL
         SELECT id,Factor - 1,count
         FROM   cte
         WHERE  Factor > 1)
SELECT a.ID,b.Factor,a.Count
FROM   cte a
       JOIN #tablename b
         ON a.Count = b.Count
ORDER  BY id 

输出

ID  Factor  Count
--  ------  -----
1   1       235
2   2       345
2   2       345
3   2       214
3   2       214
4   3       95
4   3       95
4   3       95
5   1       135
6   1       750