sql >> Databasteknik >  >> RDS >> Sqlserver

Returnerar n:te värde från resultat eller NULL

Använd ROW_NUMBER() . Tilldela först varje post ett radnummer:

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;

Sedan kan du använda detta RowNumber kolumnen till PIVOT dina data:

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;

REDIGERA

Om du inte förstår så har jag inte svarat ordentligt! Jag tror starkt på ordspråket "ge en man en fisk och du matar honom för en dag; lär en man att fiska och du matar honom för hela livet"

Om du har följande data i dina två tabeller:

Attribut '

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

ClientContactAttributes

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

Kör följande:

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;

Kommer att ge dig:

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

ROW_NUMBER() funktionen tilldelar helt enkelt ett unikt nummer till varje grupp (definierad i PARTITION BY sats), och detta nummer bestäms av ORDER BY klausul. så denna rad:

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

Säger i huvudsak för varje unikt värde för cca.ClientContactId Jag skulle vilja ha ett unikt nummer, som börjar på 1, där det lägsta värdet på attributeId tar emot 1 och antalet ökar därifrån:

PIVOT-funktionen är ungefär som en excel-pivottabell, där du vill konvertera raderna till kolumner. Den har två grundläggande delar, och jag kommer att arbeta baklänges här. Den första delen är FOR klausul:

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

Detta är värdena från RowNumber kolumn som du vill förvandla till rader. Kolumnnamnen kommer att motsvara de angivna värdena. Den andra delen (först logiskt läsning), definierar värdena som kommer att gå in i dessa nyskapade kolumner. Detta måste vara en aggregerad funktion, och i det här fallet är det:

MAX(Description)

Eftersom du redan vet att RowNumber är unik för varje ClientContactId , aggregatfunktionen (som krävs för PIVOT`) är faktiskt meningslös, eftersom det bara finns ett värde för beskrivning att aggregera.

Förhoppningsvis är detta lite mer vettigt.




  1. Docker mysql kan inte ansluta till behållaren

  2. välj * från tabell vs välj colA, colB, etc. från tabell intressant beteende i SQL Server 2005

  3. Hur man får värden som inte innehåller siffror i MariaDB

  4. Hitta dubbletter av värden i MySQL