从SQL Server中的现有行插入范围

时间:2017-08-31 22:28:45

标签: sql-server database

我在SQL Server 2008中有一个包含值范围的现有表SPLICE

+--------+----------+--------+--------------+
|OBJECTID|STARTRANGE|ENDRANGE|SOMEOTHERVALUE|
+--------+----------+--------+--------------+
|1       |2         |5       |ASDF          |
|2       |7         |7       |JKL           |
|3       |19        |20      |QWERTY        |

对于SPLICE中的每一行,我想为STARTRANGE和ENDRANGE之间的每个值插入一个新表SPLICE_INDIVIDUAL 1行:

+--------+---+--------------+
|OBJECTID| V |SOMEOTHERVALUE|
+--------+---+--------------+
|1       |2  |ASDF          |
|1       |3  |ASDF          |
|1       |4  |ASDF          |
|1       |5  |ASDF          |
|2       |7  |JKL           |
|3       |19 |QWERTY        |
|3       |20 |QWERTY        |

最好(最快,最可读)的方法是什么?

3 个答案:

答案 0 :(得分:2)

这是一个好的Tally功能真正有用的地方......

这是我在一段时间后创建的代码。

IF OBJECT_ID('tempdb..#SPLICE', 'U') IS NOT NULL 
DROP TABLE #SPLICE;

CREATE TABLE #SPLICE (
    OBJECTID INT NOT NULL,
    STARTRANGE INT NOT NULL,
    ENDRANGE INT NOT NULL,
    SOMEOTHERVALUE VARCHAR(6) NOT NULL 
    );
INSERT #SPLICE (OBJECTID, STARTRANGE, ENDRANGE, SOMEOTHERVALUE) VALUES
    (1, 2 , 5 , 'ASDF'),
    (2, 7 , 7 , 'JKL'),  
    (3, 19, 20, 'QWERTY');

IF OBJECT_ID('tempdb..#SPLICE_INDIVIDUAL', 'U') IS NOT NULL 
DROP TABLE #SPLICE_INDIVIDUAL;

CREATE TABLE #SPLICE_INDIVIDUAL (
    OBJECTID INT NOT NULL,
    V INT NOT NULL,
    SOMEOTHERVALUE VARCHAR(6) NOT NULL 
    );
INSERT #SPLICE_INDIVIDUAL (OBJECTID, V, SOMEOTHERVALUE)
SELECT 
    s.OBJECTID,
    t.n,
    s.SOMEOTHERVALUE
FROM
    #SPLICE s
    CROSS APPLY dbo.tfn_Tally(s.ENDRANGE - s.STARTRANGE + 1, s.STARTRANGE) t;

SELECT * FROM #SPLICE_INDIVIDUAL si;

这里正在使用......

OBJECTID    V           SOMEOTHERVALUE
----------- ----------- --------------
1           2           ASDF
1           3           ASDF
1           4           ASDF
1           5           ASDF
2           7           JKL
3           19          QWERTY
3           20          QWERTY

并将数据插入SPLICE_INDIVIDUAL ...

<template v-if="!editing">
  <h1>{{ book.title }}</h1>
  <p>{{ book.description }}</p>

  <button @click="editing = false">Done</button>
</template>

<template v-else>
  <input v-model="book.title">
  <input v-model="book.description">

  <button @click="editing = true">Edit</button>
</template>

答案 1 :(得分:1)

测试数据

Declare @t TABLE (OBJECTID INT , STARTRANGE INT 
                                 , ENDRANGE INT , SOMEOTHERVALUE VARCHAR(20))
INSERT INTO @t VALUES 
(1   ,2       ,5      ,'ASDF'   ),
(2   ,7       ,7      ,'JKL'    ),
(3   ,19      ,20     ,'QWERTY' )

<强>查询

SELECT t.OBJECTID
     , t.STARTRANGE + c.Number AS V
     , t.SOMEOTHERVALUE
FROM @t t
  CROSS APPLY (
                SELECT TOP ((t.ENDRANGE + 1) - t.STARTRANGE) 
                            ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 Number
                FROM master..spt_values x CROSS JOIN master..spt_values y
              ) c

结果集

╔══════════╦════╦════════════════╗
║ OBJECTID ║ V  ║ SOMEOTHERVALUE ║
╠══════════╬════╬════════════════╣
║        1 ║  2 ║ ASDF           ║
║        1 ║  3 ║ ASDF           ║
║        1 ║  4 ║ ASDF           ║
║        1 ║  5 ║ ASDF           ║
║        2 ║  7 ║ JKL            ║
║        3 ║ 19 ║ QWERTY         ║
║        3 ║ 20 ║ QWERTY         ║
╚══════════╩════╩════════════════╝

答案 2 :(得分:0)

您可以使用另一个表(称为Tally表),其中包含数字列表1 ...

然后将此计数表连接到表中以生成其他行

例如

选择*   从tally到t   将splice加入s.startrange和s.endrange

之间的t.number上