选择一行X次

时间:2013-11-07 07:36:48

标签: sql sql-server

我有一个非常具体的SQL问题。

我有一个给定订单位置的表(每个位置属于一个订单,但这不是问题):

|  Article ID  |  Amount  |
|--------------|----------|
|     5        |    3     |
|     12       |    4     |

对于客户,我需要导出每个订购的物理项目,例如

|  Article ID  |  Position  |
|--------------|------------|
|     5        |    1       |
|     5        |    2       |
|     5        |    3       |
|     12       |    1       |
|     12       |    2       |
|     12       |    3       |
|     12       |    4       |

如何构建我的select语句给我这个结果?我认为有两个关键任务:

1)根据金额

选择一行X次

2)设置每个物理文章的位置

2 个答案:

答案 0 :(得分:6)

你可以这样做

SELECT ArticleID, n.n Position
  FROM table1 t JOIN
(
   SELECT a.N + b.N * 10 + 1 n
     FROM 
    (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
   ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
) n
    ON n.n <= t.amount
 ORDER BY ArticleID, Position

注意:子查询n从1到100生成一系列数字。如果您执行了大量此类查询,则可以考虑创建持久计数(数字)表并改为使用它。

这是 SQLFiddle 演示

或使用递归CTE

WITH tally AS (
  SELECT 1 n
  UNION ALL
  SELECT n + 1 FROM tally WHERE n < 100
)
SELECT ArticleID, n.n Position
  FROM table1 t JOIN tally n
    ON n.n <= t.amount
 ORDER BY ArticleID, Position

这是 SQLFiddle 演示

两种情况下的输出:

| ARTICLEID | POSITION |
|-----------|----------|
|         5 |        1 |
|         5 |        2 |
|         5 |        3 |
|        12 |        1 |
|        12 |        2 |
|        12 |        3 |
|        12 |        4 |

答案 1 :(得分:0)

查询:

<强> SQLFIDDLEExample

SELECT t1.[Article ID],
       t2.number 
FROM Table1 t1,
     master..spt_values t2
WHERE t1.Amount >= t2.number 
AND t2.type = 'P'
AND t2.number <= 255
AND t2.number <> 0

结果:

| ARTICLE ID | NUMBER |
|------------|--------|
|          5 |      1 |
|          5 |      2 |
|          5 |      3 |
|         12 |      1 |
|         12 |      2 |
|         12 |      3 |
|         12 |      4 |