Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Rückgabe des n-ten Werts aus Ergebnissen oder NULL

Verwenden Sie ROW_NUMBER() . Weisen Sie zunächst jedem Datensatz eine Zeilennummer zu:

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;

Dann können Sie diese RowNumber verwenden Spalte zu PIVOT Ihre Daten:

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;

BEARBEITEN

Wenn Sie nicht verstehen, dann habe ich nicht richtig geantwortet! Ich glaube fest an das Sprichwort "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag; lehre einen Mann zu fischen und du ernährst ihn ein Leben lang"

Wenn Sie die folgenden Daten in Ihren beiden Tabellen haben:

Attribute '

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

ClientContactAttributes

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

Folgendes ausführen:

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;

Gibt Ihnen:

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

Die ROW_NUMBER() Funktion weist jeder Gruppe einfach eine eindeutige Nummer zu (definiert in der PARTITION BY Klausel), und diese Nummer wird durch den ORDER BY bestimmt Klausel. also diese Zeile:

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

Bedeutet im Wesentlichen, für jeden eindeutigen Wert von cca.ClientContactId Ich hätte gerne eine eindeutige Zahl, beginnend bei 1, wobei der niedrigste Wert von attributeId ist erhält 1 und die Zahl erhöht sich von dort:

Die PIVOT-Funktion ähnelt einer Excel-Pivot-Tabelle, bei der Sie die Zeilen in Spalten umwandeln möchten. Es hat zwei grundlegende Teile, und ich werde hier rückwärts arbeiten. Der erste Teil ist der FOR Klausel:

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

Dies sind die Werte aus RowNumber Spalte, die Sie in Zeilen umwandeln möchten. Die Spaltennamen entsprechen den angegebenen Werten. Der zweite Teil (erster logisch lesender) definiert die Werte, die in diese neu erstellten Spalten eingehen. Dies muss eine Aggregatfunktion sein, und in diesem Fall ist es:

MAX(Description)

Da Sie diese RowNumber bereits kennen ist für jede ClientContactId eindeutig , die aggregierte Funktion (die für PIVOT` erforderlich ist) ist eigentlich bedeutungslos, da es nur einen Wert für die zu aggregierende Beschreibung gibt.

Hoffentlich macht das etwas mehr Sinn.