Разделение строк в SQL - PullRequest
       18

Разделение строк в SQL

1 голос
/ 21 октября 2008

Может кто-нибудь сообщить мне, как получить разные сегменты трех строк, которые по-разному пересекаются, используя SQL? Три строки в # t2 представляют наборы A, B, C - я ищу AIB, AIC, BIC, AIBIC, A ', B', C 'и т. Д. (7 возможных сегментов с 3 строками, как на диаграмме Венна) где я - пересечение.

Я ищу универсальное решение, которое может обрабатывать n строк в # t2.

-- SQL Code Begin
create table #t1 (key1 int, key2 int) -- for each Key1 there can be 1 or more Key2
go
create table #t2 (row_id int identity(101, 1), key1 int) --row_id is the primary key
go 

insert into #t1
select 1, 11 union select 1, 12 union select 1, 13 union select 1, 14 union 
select 2, 13 union select 2, 15 union select 2, 16 union select 2, 17 union 
select 3, 13 union select 3, 12 union select 3, 16 union select 3, 17

-- 1 --> 11, 12, 13, 14
-- 2 --> 13, 15, 16, 17
-- 3 --> 13, 12, 16, 17

insert into #t2 (key1)
select 1 union select 2 union select 3

-- SQL Code End

Вывод, который я ищу,

1001  11 (A')
1001  14 (A')
1002  12 (A I C - A I B I C)
1003  13 (A I B I C)
1004  15 (B')
1005  16 (B I C - A I B I C)
1005  17 (B I C - A I B I C)

Выход имеет 5 сегментов, вместо возможных 7, поскольку два из них равны NULL.

Ответы [ 3 ]

3 голосов
/ 21 октября 2008

Если я правильно понял проблему, я думаю, что вам, возможно, придется прибегнуть к использованию цикла, чтобы справиться с числом n строк

DECLARE @Key2 INT
DECLARE @Subset VARCHAR(1000)
DECLARE @tblResults TABLE
(
    Key2 INT,
    Subset VARCHAR(1000)
)

SET @Subset = ''
SELECT @Key2 = MIN(Key2) FROM #t1

WHILE @Key2 IS NOT NULL
BEGIN
    SELECT @Subset = @Subset + CAST(Key1 AS VARCHAR(10))
    FROM #t1
    WHERE Key2 = @Key2

    INSERT INTO @tblResults (Key2, Subset)
    VALUES (@Key2, @Subset)

    SET @Subset = ''
    SELECT @Key2 = MIN(Key2) FROM #t1 WHERE Key2 > @Key2
END

SELECT * FROM @tblResults
0 голосов
/ 21 октября 2008

Если вы можете заполнить таблицу 2 как

1, Key1-Value 1
2, Key1-Value 2
4, Key1-Value 3

аналогично, если у вас больше ключей key1, тогда столбец идентификаторов, который у вас есть, должен быть заполнен как двоичное дерево. так что значения в t2 будут

1 , 1
2 , 2
4 , 3

Затем вам нужно сделать выбор:

select sum(identity), key2
from t1, t2
where t1.key1 = t2.key1
groupby key2

результат, который вы получите, будет

1   11
5   12
7   13
1   14
2   15
6   16
6   17

вы можете видеть, что 1,2,4 будет A ', B', C '2 будет A | B, 7 будет A | B | C и аналогично

0 голосов
/ 21 октября 2008

Как насчет этого?

SELECT key2,
  CASE
  WHEN InA = 1 and InB = 1 and InC = 1 THEN 'ABC'
  WHEN InA = 0 and InB = 1 and InC = 1 THEN 'BC'
  WHEN InA = 1 and InB = 0 and InC = 1 THEN 'AC'
  WHEN InA = 1 and InB = 1 and InC = 0 THEN 'AB'
  WHEN InA = 1 and InB = 0 and InC = 0 THEN 'A'
  WHEN InA = 0 and InB = 1 and InC = 0 THEN 'B'
  WHEN InA = 0 and InB = 0 and InC = 1 THEN 'C'
  ELSE 'I''m broke'
  END as [SubSet]
FROM

(
SELECT key2,
  MAX(CASE WHEN key1 = 1 THEN 1 ELSE 0 END) as InA,
  MAX(CASE WHEN key1 = 2 THEN 1 ELSE 0 END) as InB,
  MAX(CASE WHEN key1 = 3 THEN 1 ELSE 0 END) as InC
FROM #t1
WHERE key1 in (1, 2, 3)
GROUP BY key2
) sub

ORDER BY key2
...