我有以下表格:
CREATE TABLE source_table (
id int IDENTITY(1, 1) NOT NULL,
category varchar(255) NULL,
item int NULL,
counter int NULL,
length int NULL
);
CREATE TABLE dest_table(
id int IDENTITY(1, 1) NOT NULL,
from_item [int] NULL,
to_item [int] NULL,
length [int] NULL
);
源表包含以下记录:
INSERT INTO source_table SELECT 'A', 100, 1, 0
INSERT INTO source_table SELECT 'A', 101, 2, 10
INSERT INTO source_table SELECT 'A', 102, 3, 5
INSERT INTO source_table SELECT 'A', 103, 4, 7
INSERT INTO source_table SELECT 'A', 104, 5, 12
INSERT INTO source_table SELECT 'B', 101, 1, 0
INSERT INTO source_table SELECT 'B', 111, 2, 15
INSERT INTO source_table SELECT 'B', 114, 3, 6
INSERT INTO source_table SELECT 'B', 117, 4, 13
INSERT INTO source_table SELECT 'B', 119, 5, 8
源表中的行需要以这样的方式进行转换,以便目标表中的每条记录代表源表中的2行。
在目标表中将上述行转换为以下内容的正确SQL语法是什么?
100, 101, 10
101, 102, 5
102, 103, 7
103, 104, 12
101, 111, 15
111, 114, 6
114, 117, 13
117, 119, 8
答案 0 :(得分:1)
您可以使用lag
窗口函数:
select *
from (select lag(item) over (partition by category order by item) as from_item,
item as to_item,
length
from source_table) base
where from_item is not null
将其插入目标表是标准的。
答案 1 :(得分:0)
执行SELF JOIN
。
<强>查询强>
insert into dest_table([from_item], [to_item], [length])
select t.* from(
select t1.[item] as col_1, t2.[item] as col_2, t2.[length]
from source_table t1
join source_table t2
on t1.id = t2.id -1
)t
where t.[length] <> 0;
结果集如下所示。
+-----+-----+------+
|col_1|col_2|length|
+-----+-----+------+
| 100 | 101 | 10 |
| 101 | 102 | 5 |
| 102 | 103 | 7 |
| 103 | 104 | 12 |
| 101 | 111 | 15 |
| 111 | 114 | 6 |
| 114 | 117 | 13 |
| 117 | 119 | 8 |
+-----+-----+------+
修改强>
如果标识列中存在间隙。然后,
<强>查询强>
;with cte as(
select rn = row_number() over(
order by id
), *
from source_table
)
insert into dest_table([from_item], [to_item], [length])
select t.* from(
select t1.[item] as col_1, t2.[item] as col_2, t2.[length]
from cte t1
join cte t2
on t1.id = t2.id -1
)t
where t.[length] <> 0;
答案 2 :(得分:0)
SELECT a.item, b.item, b.length
FROM source_table as a
INNER JOIN source_table b
ON a.id = b.id - 1
AND a.category = b.category
答案 3 :(得分:0)
如果该计数器没有间隙,那么您可以对该类别和类别进行自我加入。
例如:
DECLARE @source_table TABLE (
id int IDENTITY(1, 1) NOT NULL,
category varchar(1) NULL,
item int NULL,
[counter] int NULL,
[length] int NULL
);
DECLARE @dest_table TABLE(
id int IDENTITY(1, 1) NOT NULL,
category varchar(1) NULL,
from_item int NULL,
to_item int NULL,
[length] int NULL
);
INSERT INTO @source_table (category, item, [counter], [length]) values
('A', 100, 1, 0),
('A', 101, 2, 10),
('A', 102, 3, 5),
('A', 103, 4, 7),
('A', 104, 5, 12),
('B', 101, 1, 0),
('B', 111, 2, 15),
('B', 114, 3, 6),
('B', 117, 4, 13),
('B', 119, 5, 8);
insert into @dest_table (category, from_item, to_item, [length])
select t1.category, t1.item, t2.item, t2.[length]
from @source_table t1
join @source_table t2
on (t1.category = t2.category and t1.[counter]+1 = t2.[counter]);
select * from @dest_table;
如果Id或计数器之间存在间隙,则row_number可用于使用相同的方法 例如:
with SRC AS (
select category, item, [length],
row_number() over (partition by category order by id) as [counter]
from @source_table
)
insert into @dest_table (category, from_item, to_item, [length])
select t1.category, t1.item, t2.item, t2.[length]
from SRC t1
join SRC t2
on (t1.category = t2.category and t1.[counter]+1 = t2.[counter]);