Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Restituisce l'ennesimo valore dai risultati o NULL

Usa ROW_NUMBER() . Assegna prima a ogni record un numero di riga:

SELECT  cca.ClientContactId,
        a.Description,
        RowNumber = ROW_NUMBER() OVER(PARTITION BY cca.ClientContactId 
                                        ORDER BY a.AttributeId)
FROM    ClientContactAttributes AS cca
        INNER JOIN Attributes AS a
            ON a.AttributeId = cca.AttributeId;

Quindi puoi utilizzare questo RowNumber colonna a PIVOT i tuoi dati:

WITH Data AS
(   SELECT  cca.ClientContactId,
            a.Description,
            RowNumber = ROW_NUMBER() OVER(PARTITION BY cca.ClientContactId 
                                            ORDER BY a.AttributeId)
    FROM    ClientContactAttributes AS cca
            INNER JOIN Attributes AS a
                ON a.AttributeId = cca.AttributeId
)
SELECT  pvt.ClientContactID,
        Attribute1 = pvt.[1],
        Attribute2 = pvt.[2],
        Attribute3 = pvt.[3],
        Attribute4 = pvt.[4]
FROM    Data
        PIVOT
        (   MAX(Description)
            FOR RowNumber IN ([1], [2], [3], [4])
        ) AS pvt;

MODIFICA

Se non capisci allora non ho risposto correttamente! Credo fermamente nel proverbio "dai un pesce a un uomo e lo nutrirai per un giorno; insegna a un uomo a pescare e lo nutrirai per tutta la vita"

Se hai i seguenti dati nelle tue due tabelle:

Attributi '

AttributeId | Description
------------+---------------
    1       |     Bed          
    2       |     Bath        
    3       |    Beyond 

AttributiClientContact

ClientContactID | AttributeId
----------------+---------------
       1        |    1
       1        |    2
       1        |    3
       2        |    1

Esecuzione di quanto segue:

SELECT  cca.ClientContactId,
        a.Description,
        RowNumber = ROW_NUMBER() OVER(PARTITION BY cca.ClientContactId 
                                        ORDER BY a.AttributeId)
FROM    ClientContactAttributes AS cca
        INNER JOIN Attributes AS a
            ON a.AttributeId = cca.AttributeId;

Ti darò:

ClientContactID | Description | RowNumber
----------------+-------------+-----------
       1        |     Bed     |     1
       1        |     Bath    |     2
       1        |    Beyond   |     3
       2        |     Bed     |     1

Il ROW_NUMBER() La funzione assegna semplicemente un numero univoco a ciascun gruppo (definito nel PARTITION BY clausola), e questo numero è determinato da ORDER BY clausola. quindi questa riga:

ROW_NUMBER() OVER(PARTITION BY cca.ClientContactId ORDER BY a.AttributeId)

In sostanza sta dicendo, per ogni valore univoco di cca.ClientContactId Vorrei un numero univoco, a partire da 1, dove il valore più basso di attributeId riceve 1 e il numero aumenta da lì:

La funzione PIVOT è molto simile a una tabella pivot di Excel, in cui si desidera convertire le righe in colonne. Ha due parti fondamentali e qui lavorerò a ritroso. La prima parte è il FOR clausola:

FOR RowNumber IN ([1], [2], [3], [4])

Questi sono i valori di RowNumber colonna che vuoi trasformare in righe. I nomi delle colonne corrisponderanno ai valori forniti. La seconda parte (prima lettura logica), definisce i valori che andranno in queste colonne appena create. Questa deve essere una funzione aggregata, e in questo caso è:

MAX(Description)

Dal momento che conosci già quel RowNumber è univoco per ogni ClientContactId , la funzione di aggregazione (necessaria per PIVOT`) è in realtà priva di significato, poiché esiste un solo valore per la descrizione da aggregare.

Speriamo che questo abbia un po' più senso.