Sql 基于多个条件和列将列数据拆分为单独的列
我需要拆分下面给出的列数据,包括查询和值Sql 基于多个条件和列将列数据拆分为单独的列,sql,sql-server,Sql,Sql Server,我需要拆分下面给出的列数据,包括查询和值 create table dep ( a1 varchar(17), a2 char(2), a3 varchar(50), a4 int, a5 int, a6 int, a7 char(1) ) insert into dep (a1,a2,a3,a4,a5,a6,a7) values(507,01,'abc1',30,1,2,1) insert into dep (a1,a2,a3,a4,
create table dep (
a1 varchar(17),
a2 char(2),
a3 varchar(50),
a4 int,
a5 int,
a6 int,
a7 char(1)
)
insert into dep (a1,a2,a3,a4,a5,a6,a7) values(507,01,'abc1',30,1,2,1)
insert into dep (a1,a2,a3,a4,a5,a6,a7) values(507,02,'abc2',31,2,1,0)
insert into dep (a1,a2,a3,a4,a5,a6,a7) values(507,03,'abc3',32,1,6,1)
insert into dep (a1,a2,a3,a4,a5,a6,a7) values(507,04,'abc4',33,1,3,0)
insert into dep (a1,a2,a3,a4,a5,a6,a7) values(507,05,'abc5',34,2,4,1)
需要拆分a2列及其对应的a3、a4、a5列。
输出如下:
a1 b1 b2 b3 b4 b5 c1 c2 c3 c4 c5 d1 d2 d3 d4 d5
507 abc 01 30 1 2 abc3 03 32 1 6 abc5 05 34 2 4
如果a7为0,则应跳过该记录。IMHO;如果我正确理解你的要求;我认为,作为静态查询,您可以使用如下查询:
SELECT a1
, MAX(CASE WHEN rn = 1 THEN a2 END) b1
, MAX(CASE WHEN rn = 1 THEN a3 END) b2
, MAX(CASE WHEN rn = 1 THEN a4 END) b3
, MAX(CASE WHEN rn = 1 THEN a5 END) b4
, MAX(CASE WHEN rn = 1 THEN a6 END) b5
, MAX(CASE WHEN rn = 2 THEN a2 END) c1
, MAX(CASE WHEN rn = 2 THEN a3 END) c2
, MAX(CASE WHEN rn = 2 THEN a4 END) c3
, MAX(CASE WHEN rn = 2 THEN a5 END) c4
, MAX(CASE WHEN rn = 2 THEN a6 END) c5
, MAX(CASE WHEN rn = 3 THEN a2 END) d1
, MAX(CASE WHEN rn = 3 THEN a3 END) d2
, MAX(CASE WHEN rn = 3 THEN a4 END) d3
, MAX(CASE WHEN rn = 3 THEN a5 END) d4
, MAX(CASE WHEN rn = 3 THEN a6 END) d5
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY a2) as rn
FROM dep
WHERE a7 = 1) t
GROUP BY a1;
DECLARE @sql varchar(max) = 'SELECT a1';
SELECT
@sql = @sql + ',MAX(CASE WHEN rn = ' + CAST(rn as varchar(5)) + ' THEN a2 END) ' + CHAR(64 + rn) + '1'
+ ',MAX(CASE WHEN rn = ' + CAST(rn as varchar(5)) + ' THEN a3 END) ' + CHAR(64 + rn) + '1'
+ ',MAX(CASE WHEN rn = ' + CAST(rn as varchar(5)) + ' THEN a4 END) ' + CHAR(64 + rn) + '1'
+ ',MAX(CASE WHEN rn = ' + CAST(rn as varchar(5)) + ' THEN a5 END) ' + CHAR(64 + rn) + '1'
FROM (
SELECT *
, ROW_NUMBER() OVER (ORDER BY a2) as rn
FROM #dep
WHERE a7 = 1) t;
SET @sql = @sql + 'FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY a2) as rn FROM dep WHERE a7 = 1) t GROUP BY a1';
EXEC(@sql);
DECLARE @sql nvarchar(max) = 'SELECT FamilyId', @maxDepe int;
SELECT @maxDepe = max(seq)
FROM (
SELECT *
, ROW_NUMBER() OVER (PARTITION BY FamilyId ORDER BY MemberID) As seq
FROM depe) dt;
WITH CTE(i) AS (
SELECT 1
UNION ALL
SELECT i + 1
FROM CTE
WHERE i < @maxDepe)
SELECT @sql = @sql +
',MAX(CASE WHEN seq = ' + CAST(i as varchar(3)) + ' THEN MemberName END) Dependent_' + CAST(i as varchar(3)) +
',MAX(CASE WHEN seq = ' + CAST(i as varchar(3)) + ' THEN Age END) Age_' + CAST(i as varchar(3)) +
',MAX(CASE WHEN seq = ' + CAST(i as varchar(3)) + ' THEN Gender END) Gender_' + CAST(i as varchar(3)) +
',MAX(CASE WHEN seq = ' + CAST(i as varchar(3)) + ' THEN RelationCode END) RelationCode_' + CAST(i as varchar(3))
FROM CTE;
SELECT @sql = @sql + ' FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY FamilyId ORDER BY MemberID) seq FROM depe) dt GROUP BY FamilyId';
EXEC(@sql);
动态SQL的解决方案可以是这样的:
SELECT a1
, MAX(CASE WHEN rn = 1 THEN a2 END) b1
, MAX(CASE WHEN rn = 1 THEN a3 END) b2
, MAX(CASE WHEN rn = 1 THEN a4 END) b3
, MAX(CASE WHEN rn = 1 THEN a5 END) b4
, MAX(CASE WHEN rn = 1 THEN a6 END) b5
, MAX(CASE WHEN rn = 2 THEN a2 END) c1
, MAX(CASE WHEN rn = 2 THEN a3 END) c2
, MAX(CASE WHEN rn = 2 THEN a4 END) c3
, MAX(CASE WHEN rn = 2 THEN a5 END) c4
, MAX(CASE WHEN rn = 2 THEN a6 END) c5
, MAX(CASE WHEN rn = 3 THEN a2 END) d1
, MAX(CASE WHEN rn = 3 THEN a3 END) d2
, MAX(CASE WHEN rn = 3 THEN a4 END) d3
, MAX(CASE WHEN rn = 3 THEN a5 END) d4
, MAX(CASE WHEN rn = 3 THEN a6 END) d5
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY a2) as rn
FROM dep
WHERE a7 = 1) t
GROUP BY a1;
DECLARE @sql varchar(max) = 'SELECT a1';
SELECT
@sql = @sql + ',MAX(CASE WHEN rn = ' + CAST(rn as varchar(5)) + ' THEN a2 END) ' + CHAR(64 + rn) + '1'
+ ',MAX(CASE WHEN rn = ' + CAST(rn as varchar(5)) + ' THEN a3 END) ' + CHAR(64 + rn) + '1'
+ ',MAX(CASE WHEN rn = ' + CAST(rn as varchar(5)) + ' THEN a4 END) ' + CHAR(64 + rn) + '1'
+ ',MAX(CASE WHEN rn = ' + CAST(rn as varchar(5)) + ' THEN a5 END) ' + CHAR(64 + rn) + '1'
FROM (
SELECT *
, ROW_NUMBER() OVER (ORDER BY a2) as rn
FROM #dep
WHERE a7 = 1) t;
SET @sql = @sql + 'FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY a2) as rn FROM dep WHERE a7 = 1) t GROUP BY a1';
EXEC(@sql);
DECLARE @sql nvarchar(max) = 'SELECT FamilyId', @maxDepe int;
SELECT @maxDepe = max(seq)
FROM (
SELECT *
, ROW_NUMBER() OVER (PARTITION BY FamilyId ORDER BY MemberID) As seq
FROM depe) dt;
WITH CTE(i) AS (
SELECT 1
UNION ALL
SELECT i + 1
FROM CTE
WHERE i < @maxDepe)
SELECT @sql = @sql +
',MAX(CASE WHEN seq = ' + CAST(i as varchar(3)) + ' THEN MemberName END) Dependent_' + CAST(i as varchar(3)) +
',MAX(CASE WHEN seq = ' + CAST(i as varchar(3)) + ' THEN Age END) Age_' + CAST(i as varchar(3)) +
',MAX(CASE WHEN seq = ' + CAST(i as varchar(3)) + ' THEN Gender END) Gender_' + CAST(i as varchar(3)) +
',MAX(CASE WHEN seq = ' + CAST(i as varchar(3)) + ' THEN RelationCode END) RelationCode_' + CAST(i as varchar(3))
FROM CTE;
SELECT @sql = @sql + ' FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY FamilyId ORDER BY MemberID) seq FROM depe) dt GROUP BY FamilyId';
EXEC(@sql);
编辑:在您的情况下,我认为您可以使用如下查询:
SELECT a1
, MAX(CASE WHEN rn = 1 THEN a2 END) b1
, MAX(CASE WHEN rn = 1 THEN a3 END) b2
, MAX(CASE WHEN rn = 1 THEN a4 END) b3
, MAX(CASE WHEN rn = 1 THEN a5 END) b4
, MAX(CASE WHEN rn = 1 THEN a6 END) b5
, MAX(CASE WHEN rn = 2 THEN a2 END) c1
, MAX(CASE WHEN rn = 2 THEN a3 END) c2
, MAX(CASE WHEN rn = 2 THEN a4 END) c3
, MAX(CASE WHEN rn = 2 THEN a5 END) c4
, MAX(CASE WHEN rn = 2 THEN a6 END) c5
, MAX(CASE WHEN rn = 3 THEN a2 END) d1
, MAX(CASE WHEN rn = 3 THEN a3 END) d2
, MAX(CASE WHEN rn = 3 THEN a4 END) d3
, MAX(CASE WHEN rn = 3 THEN a5 END) d4
, MAX(CASE WHEN rn = 3 THEN a6 END) d5
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY a2) as rn
FROM dep
WHERE a7 = 1) t
GROUP BY a1;
DECLARE @sql varchar(max) = 'SELECT a1';
SELECT
@sql = @sql + ',MAX(CASE WHEN rn = ' + CAST(rn as varchar(5)) + ' THEN a2 END) ' + CHAR(64 + rn) + '1'
+ ',MAX(CASE WHEN rn = ' + CAST(rn as varchar(5)) + ' THEN a3 END) ' + CHAR(64 + rn) + '1'
+ ',MAX(CASE WHEN rn = ' + CAST(rn as varchar(5)) + ' THEN a4 END) ' + CHAR(64 + rn) + '1'
+ ',MAX(CASE WHEN rn = ' + CAST(rn as varchar(5)) + ' THEN a5 END) ' + CHAR(64 + rn) + '1'
FROM (
SELECT *
, ROW_NUMBER() OVER (ORDER BY a2) as rn
FROM #dep
WHERE a7 = 1) t;
SET @sql = @sql + 'FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY a2) as rn FROM dep WHERE a7 = 1) t GROUP BY a1';
EXEC(@sql);
DECLARE @sql nvarchar(max) = 'SELECT FamilyId', @maxDepe int;
SELECT @maxDepe = max(seq)
FROM (
SELECT *
, ROW_NUMBER() OVER (PARTITION BY FamilyId ORDER BY MemberID) As seq
FROM depe) dt;
WITH CTE(i) AS (
SELECT 1
UNION ALL
SELECT i + 1
FROM CTE
WHERE i < @maxDepe)
SELECT @sql = @sql +
',MAX(CASE WHEN seq = ' + CAST(i as varchar(3)) + ' THEN MemberName END) Dependent_' + CAST(i as varchar(3)) +
',MAX(CASE WHEN seq = ' + CAST(i as varchar(3)) + ' THEN Age END) Age_' + CAST(i as varchar(3)) +
',MAX(CASE WHEN seq = ' + CAST(i as varchar(3)) + ' THEN Gender END) Gender_' + CAST(i as varchar(3)) +
',MAX(CASE WHEN seq = ' + CAST(i as varchar(3)) + ' THEN RelationCode END) RelationCode_' + CAST(i as varchar(3))
FROM CTE;
SELECT @sql = @sql + ' FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY FamilyId ORDER BY MemberID) seq FROM depe) dt GROUP BY FamilyId';
EXEC(@sql);
您正在使用什么RDBMS?你是说对应栏而不是对应栏吗?a2、a3、a4等也发生了什么?您是否试图转置a7!=0?使用sql server 2014,a1是主列,我需要根据a1、a2和a7拆分数据假设如果a2=01和a7=1,那么数据应该拆分为01,就像我从a4、a5、a6列名b1、b2、c1中的对应列数据拆分一样,c2是定义的输出列名如果a2=02和a7=0,则的数据不应拆分,它应检查下一行的a2和a7值如果a2值为1到16,并且基于a1和a2的分组,只有a7状态只能为1到5?我有数百万行,a2只有16个唯一值选择URN,当rn=1时选择MAXCASE,然后选择MemberID END b1,rn=1时的MAXCASE,然后是MemberName END b2;rn=1时的MAXCASE,然后是MemberName END b3;rn=1时的MAXCASE,然后是年龄END b4;rn=1时的MAXCASE,然后是RelationCode END b5;rn=2时的MAXCASE,然后是MemberID END c1;rn=2时的MAXCASE,然后是MemberName END c2;rn=2时的MAXCASE,然后是性别END c3,当rn=2时MAXCASE结束c4,当rn=2时MAXCASE结束c5,当rn=3时MAXCASE结束d1,当rn=3时MAXCASE结束d2,当rn=3时MAXCASE结束d3,当rn=3时MAXCASE结束d4,当rn=3时MAXCASE结束d5,rn=4时的MAXCASE,然后是MemberID端e1;rn=4时的MAXCASE,然后是MemberName端e2;rn=4时的MAXCASE,然后是性别端e3;rn=4时的MAXCASE,然后是年龄端e4;rn=4时的MAXCASE,然后是关系代码端e5;rn=5时的MAXCASE,然后是MemberID端f1;rn=5时的MAXCASE,然后是MemberName端f2,rn=5时的MAXCASE,然后是性别结束f3,rn=5时的MAXCASE,然后是年龄结束f4,rn=5时的MAXCASE,然后是关系代码结束f5,从SELECT*,按成员ID排序的行数作为rn,从从属位置注册='1't按URN分组;