sql >> Base de Datos >  >> RDS >> Sqlserver

Devolviendo el valor enésimo de los resultados o NULL

Use ROW_NUMBER() . Primero asigne a cada registro un número de fila:

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;

Entonces puedes usar este RowNumber columna a PIVOT tus datos:

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;

EDITAR

¡Si no entiendes, entonces no he respondido correctamente! Creo firmemente en el proverbio "dale un pescado a un hombre y lo alimentarás por un día; enséñale a pescar y lo alimentarás para toda la vida"

Si tiene los siguientes datos en sus dos tablas:

Atributos '

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

Atributos de contacto del cliente

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

Ejecutando lo siguiente:

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;

Te dará:

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

El ROW_NUMBER() simplemente asigna un número único a cada grupo (definido en la PARTITION BY cláusula), y este número está determinado por el ORDER BY cláusula. así que esta línea:

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

Esencialmente dice, para cada valor único de cca.ClientContactId Me gustaría un número único, comenzando en 1, donde el valor más bajo de attributeId recibe 1 y el número aumenta a partir de ahí:

La función PIVOT es muy parecida a una tabla dinámica de Excel, donde desea convertir las filas en columnas. Tiene dos partes fundamentales, y aquí trabajaré al revés. La primera parte es FOR cláusula:

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

Estos son los valores de RowNumber columna que desea convertir en filas. Los nombres de las columnas corresponderán a los valores proporcionados. La segunda parte (primera lectura lógica), define los valores que irán en estas columnas recién creadas. Esta tiene que ser una función agregada, y en este caso es:

MAX(Description)

Como ya sabes que RowNumber es único para cada ClientContactId , la función agregada (que se requiere para PIVOT`) en realidad no tiene sentido, ya que solo hay un valor para que la descripción agregue.

Esperemos que esto tenga un poco más de sentido.