在相同条件下将列一分为二

时间:2019-01-15 13:53:51

标签: sql sql-server substring case

我有一个名为X的列,该列中实际上存储了2种不同的信息。我知道如何拆分它们,但我希望得到比我的查询优化的东西,或者至少要优化的东西。

我有一个正在运行的查询,但我希望它在处理大量数据时遇到困难。

  SELECT
    CASE SUBSTRING(X,1,3)
      WHEN 'AAA' THEN SUBSTRING(X,1,10)
      WHEN 'BBB' THEN SUBSTRING(X,1,20)
    END as firstinfo,
    CASE SUBSTRING(X,1,3)
      WHEN 'AAA' THEN SUBSTRING(X,11,5)
      WHEN 'BBB' THEN SUBSTRING(X,21,5)
    END as secondinfo
  FROM Table

结果是这样的:

      firstinfo     |secondinfo
------------------------------
AAAfstdata          |smthg
BBBfirstdatalongerXX|else

由于casewhen的条件相同,所以只能有一个条件,显示2列

2 个答案:

答案 0 :(得分:0)

您可以使用XML技巧来拆分它们。

示例片段:

declare @Table table (X varchar(30));

insert into @Table (X) values
('AAAfstdatasmthg'),
('BBBfirstdatalongerXXelse'),
('ZZZ4567890123456789012345');

SELECT 
X2.value('/x[1]','varchar(30)') as firstinfo,
X2.value('/x[2]','varchar(30)') as secondinfo
FROM @Table
CROSS APPLY (
   SELECT 
   CAST('<x>'+STUFF(X, 
         case LEFT(X,3) 
         when 'AAA' then 11 
         when 'BBB' then 21 
         else LEN(X)-4 
         end
         ,0,'</x><x>')+'</x>' AS XML) AS X2
) as ca;

或使用VALUES

示例片段:

declare @Table table (X varchar(30));

insert into @Table (X) values
('AAAfstdatasmthg'),
('BBBfirstdatalongerXXelse'),
('ZZZ4567890123456789012345');

SELECT 
LEFT(X, COALESCE(pos, LEN(X)-5)) as firstinfo,
SUBSTRING(X, COALESCE(pos, LEN(X)-4), IIF(pos is not null, LEN(X)-pos+1, 5)) as secondinfo
FROM @Table t
LEFT JOIN (VALUES 
 ('AAA',11),
 ('BBB',21)
) v(code, pos) ON v.code = LEFT(X,3);

结果:

firstinfo               secondinfo
-------------           ----------
AAAfstdata              smthg
BBBfirstdatalongerXX    else
ZZZ45678901234567890    12345

但是对于这个例子,我猜可能还需要关注secondinfo的长度:

SELECT 
LEFT(X,      case LEFT(X,3) when 'BBB' then LEN(X)-4 else LEN(X)-5 end) as firstinfo,
SUBSTRING(X, case LEFT(X,3) when 'BBB' then LEN(X)-3 else LEN(X)-4 end, 5) as secondinfo
FROM @Table;

答案 1 :(得分:-1)

您可以使用PIVOT将数据分为具有自己数据的列。这就是PIVOT的工作方式

SELECT * FROM table1
PIVOT(
       SUM(Sales) -- for strings use MAX(comment) for example.
       FOR X --this is the column which will be split into parts
       IN (First_Hand, Second_Hand) --this creates 2 columns
) AS PIVOT1

样本 来自名为Drinks的表的原始数据

enter image description here

使用PIVOT后

选择*从temp.dbo.drinks 枢(         SUM(avail_amt)         位置         输入(CA,DC,FL)         )PIV1

然后结果

enter image description here