我已搜索SQL Server : rows into columns将行值拆分为列,但这对我没有帮助
我有样本数据
Col1
0183125031218
13020690831
79100146868
0183225031138
13010690834
79100145497
预期产出:
Col1 Col2 Col3
0183125031128 13020690831 79100146868
0183225031138 13010690834 79100145497
我的尝试:
我尝试使用Row_number
功能,但未获得所需的输出。因为我需要left(col,2) = 01
到第一列和left(col,2)=13
到第二列的条件分割。基于第一列,可以分配行号。任何行数据都没有固定长度
Apreciate任何帮助或建议
答案 0 :(得分:2)
尝试以下查询
-- test data
CREATE TABLE TestData(Col1 varchar(20))
INSERT TestData(Col1)VALUES
('0183125031218'),
('13020690831'),
('79100146868'),
('0183225031138'),
('1301069083'),
('79100145497')
-- query
SELECT
COALESCE(q1.N,q2.N,q3.N) RowNum,
q1.Col1,
q2.Col1 Col2,
q3.Col1 Col3
FROM
(
SELECT ROW_NUMBER()OVER(ORDER BY Col1) N,Col1
FROM TestData
WHERE Col1 LIKE '01%'
) q1
FULL JOIN
(
SELECT ROW_NUMBER()OVER(ORDER BY Col1) N,Col1
FROM TestData
WHERE Col1 LIKE '13%'
) q2
ON q2.N=q1.N
FULL JOIN
(
SELECT ROW_NUMBER()OVER(ORDER BY Col1) N,Col1
FROM TestData
WHERE Col1 LIKE '79%'
) q3
ON q3.N=COALESCE(q1.N,q2.N)
带有PIVOT
SELECT *
FROM
(
SELECT
LEFT(Col1,2) RowType,
ROW_NUMBER()OVER(PARTITION BY LEFT(Col1,2) ORDER BY Col1) N,
Col1
FROM TestData
) q PIVOT(MAX(Col1) FOR RowType IN([01],[13],[79])) p
答案 1 :(得分:2)
如何使用CTE分配行号和分组?
CREATE TABLE #Sample (Col1 varchar(50));
GO
INSERT INTO #Sample
VALUES ('0183125031218'),
('13020690831'),
('79100146868'),
('0183225031138'),
('1301069083'),
('79100145497');
GO
SELECT *
FROM #SAmple;
WITH Grp AS(
SELECT Col1,
LEFT(Col1,2) AS Grp,
ROW_NUMBER() OVER (PARTITION BY LEFT(Col1,2) ORDER BY Col1) AS RN
FROM #Sample)
SELECT G1.Col1 AS Col1,
G2.Col1 AS Col2,
G3.Col1 AS Col3
FROM Grp G1
JOIN Grp G2 ON G1.RN = G2.RN
AND G2.Grp = '13'
JOIN Grp G3 ON G1.RN = G3.RN
AND G3.Grp = '79'
WHERE G1.Grp = '01';
GO
DROP TABLE #Sample;
这使得查询比在leran2002的答案中使用UNION
更简洁/更短。
答案 2 :(得分:1)
试试这个。背后的想法是根据给定的条件将表拆分为三列,然后根据row_number()
将它们连接回来,没有任何排序,因为你告诉特定记录之间没有关系。
declare @table table(col1 varchar(100))
insert into @table values
('0183125031218'),
('13020690831'),
('79100146868'),
('0183225031138'),
('1301069083'),
('79100145497')
select [col1],[col2],[col3] from
--IMPORTANT: here should go the query, that will have the most records!!!
(select col1 [col1], ROW_NUMBER() over (order by (select null)) [rn1] from @table where LEFT(col1, 2) = '01') [c1]
left join
(select col1 [col2], ROW_NUMBER() over (order by (select null)) [rn2] from @table where LEFT(col1, 2) = '13') [c2]
on [rn1]=[rn2] left join
(select col1 [col3], ROW_NUMBER() over (order by (select null)) [rn3] from @table where not LEFT(col1, 2) in ('01','13')) [c3]
on [rn1]=[rn3]
答案 3 :(得分:0)
与Larnu(+1)相同 我只是想测试一下
declare @T TABLE (col varchar(50));
INSERT INTO @T
VALUES ('0183125031218'),
('13020690831'),
('79100146868'),
('0183225031138'),
('13010690834'),
('79100145497');
SELECT *
FROM @T;
WITH cte AS
( SELECT col, LEFT(col,2) AS grp,
ROW_NUMBER() OVER (PARTITION BY LEFT(col,2) ORDER BY col) AS rn
FROM @T
where LEFT(col,2) in ('01', '13', '79')
)
SELECT G1.col AS Col1,
G2.col AS Col2,
G3.col AS Col3
FROM cte G1
JOIN cte G2 ON G1.RN = G2.RN
and G1.Grp = '01'
AND G2.Grp = '13'
JOIN cte G3 ON G1.RN = G3.RN
AND G3.Grp = '79'
order by G1.col, G2.col, G3.col;