Разделить столбец на две части с одинаковыми условиями - PullRequest
0 голосов
/ 15 января 2019

У меня есть столбец с именем 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

Было бы возможно иметь только одно условие, поскольку это те же самые условия case и when, показывающие 2 столбца

Ответы [ 2 ]

0 голосов
/ 15 января 2019

вы можете использовать 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

SAMPLE Исходные данные из таблицы с названием Drinks

enter image description here

После того, как я использовал PIVOT

ВЫБРАТЬ * ИЗ ТЕМП.1019 *

0 голосов
/ 15 января 2019

Вы можете использовать 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;

Или используйте ЗНАЧЕНИЯ

Пример фрагмента:

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;
...