2015-07-01 12 views
17

consente di dire, abbiamo questa tabella:Come per contare il numero di volte in cui due valori vengono visualizzati in due colonne in qualsiasi ordine

+------+------+ 
| COL1 | COL2 | 
+------+------+ 
| A | B | 
+------+------+ 
| B | A | 
+------+------+ 
| C | D | 
+------+------+ 

voglio contare il numero di volte in cui sia letter1, letter2 o letter2, letter1 appare nei due colonne.

voglio il risultato:

+------+------+------+ 
| COL1 | COL2 | COL3 | 
+------+------+------+ 
| A | B | 2 | 
+------+------+------+ 
| C | D | 1 | 
+------+------+------+ 

NOTA: può essere sia AB o BA non importa.

ho provato:

SELECT 
COL1,COL1,COUNT(*) AS COL3 
FROM 
X 
GROUP BY COL1,COL2; 

Ma che mi fa:

+------+------+------+ 
| COL1 | COL2 | COL3 | 
+------+------+------+ 
| A | B | 1 | 
+------+------+------+ 
| B | A | 1 | 
+------+------+------+ 
| C | D | 1 | 
+------+------+------+ 
+0

Qualcosa di simile si ottiene con una "matrice di covarianza." Tuttavia i risultati dovrebbero ancora essere uniti, rispettivamente sommati. – AnyOneElse

risposta

15

È possibile farlo scambiando le colonne se è necessario:

SELECT Col1, Col2, COUNT(*) 
FROM 
(
    SELECT 
     CASE WHEN Col1 < Col2 THEN Col1 ELSE Col2 END AS Col1, 
     CASE WHEN Col1 < Col2 THEN Col2 ELSE Col1 END AS Col2 
    FROM T 
) t 
GROUP BY Col1, Col2 

Fiddle

+6

Puoi renderlo più elegante usando 'LEAST',' GREATEST' e eliminando la query esterna, come [this] (http://sqlfiddle.com/#!9/7c4f77/3). +1 per una bella domanda però. –

+2

@GiorgosBetsos - Preferisco scrivere SQL che funzioni su tutte le piattaforme, ove possibile. –

0

UPDATE:: risposta Usa @Damien s'. Un altro tentativo.

Puoi provare il codice qui sotto. Fiddle

SELECT COL1, COL2, COUNT(*) AS COL3 
    FROM (
    SELECT 
    LEAST(COL1,COL2) AS COL1, 
    GREATEST(COL1,COL2) AS COL2 
    FROM X 
    ) AS Temp 
    GROUP BY COL1,COL2; 
+1

CTE è specifico per SQL Server. https://msdn.microsoft.com/en-us/library/ms190766.aspx – rurouni88

+1

@ rurouni88 - non è specifico di SQL Server. È standard SQL (anche Oracle e Postgre lo supportano). È solo che MySQL non segue lo standard qui. –

+0

@Damien_The_Unbeliever: abbastanza giusto. In ogni caso, non è supportato qui. Non mi fai andare in giro. Ho passato la scorsa settimana a guardare diverse piattaforme DB diverse implementazioni di RAND() con SEED(): P – rurouni88

-1

Vedi http://sqlfiddle.com/#!9/4bd6a/23

Usa se le dichiarazioni e concat le 2 colonne.

SELECT 
    DISTINCT (CONCAT(C1,C2)) AS permutation, COUNT(1) 
    FROM (SELECT 
    IF(col1<=col2, col1, col2) as C1, 
    IF(col2<col1, col1, col2) as C2 
    FROM X) AS T 
    GROUP BY permutation 
; 

Ulteriori spiegazioni: Il if semplicemente ordinare i caratteri per valore ASCII, Quindi, indipendentemente dal 'AB' o 'BA', sarà sempre rappresentato come 'AB'

+0

Potrebbe funzionare con valori di un carattere, ma se i valori reali erano "AA" e "BB" ciò corrisponderebbe falsamente a "AAB" e "B". – abligh

3

Un'altra prova

SELECT LEAST(col1, col2) col11, GREATEST(col1, col2) col12 , COUNT(1) FROM X 
GROUP BY col11, col12 

SqlFiddle

+1

Mi piace questa risposta la migliore. È molto più breve e più leggibile. – AdamMc331

Problemi correlati