Domanda

Qualcuno può farmi sapere come ottenere i diversi segmenti delle tre righe che si intersecano in modi diversi utilizzando SQL? Le tre righe in # t2 rappresentano i set A, B, C - Sto cercando AIB, AIC, BIC, AIBIC, A ', B', C 'ecc. (7 possibili segmenti con 3 righe come in un diagramma di Venn) dove io sono l'intersezione.

Sto cercando una soluzione generica in grado di gestire n numero di righe in # 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

L'output che sto cercando è,

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)

L'output ha 5 segmenti, anziché i 7 possibili, poiché due di essi sono NULL.

È stato utile?

Soluzione

Se ho compreso correttamente il problema, penso che potresti dover ricorrere all'uso di un ciclo per far fronte al numero 'n' di righe

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

Altri suggerimenti

Che ne dici di questo?

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

Se puoi popolare la tabella 2 come

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

allo stesso modo se hai più key1 allora la colonna identità come hai, dovrebbe essere popolata come un albero binario. in modo che i valori in t2 siano

1 , 1
2 , 2
4 , 3

Quindi devi selezionare:

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

l'output che otterrai sarà

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

puoi vedere che 1,2,4 sarà A ', B', C '2 sarà A | B, 7 sarà A | B | C e allo stesso modo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top