2011-04-26 5 views
5

En PostgreSQL, existe esta función string_agg muy útil, que permite la consulta como:Porting PostgreSQL string_agg a SQL Server, un problema con ORDER BY

SELECT 
    contacts.first_name, 
    contacts.last_name, 
    (
     SELECT 
      string_agg(number, ', ' ORDER BY phones.priority) 
     FROM 
      phones 
     WHERE 
      phones.contact_id = contacts.id 
    ) AS phone_numbers 
FROM 
    contacts 

Del mismo modo, esto se puede hacer en MySQL utilizando GROUP_CONCAT.

Ahora, intento portar esto en SQL Server como agregado CLR definido por el usuario. El código en sí no es un problema, ya que hay miles de ejemplos en toda la web para crear este agregado en particular (lo que plantea la pregunta: ¿por qué ya no forma parte de SQL Server?).

El problema es que no puedo encontrar una manera limpia de aplicar el ORDER BY, ya que SQL Server no solo no admite ORDER BY en la función de agregado, sino que también prohíbe el uso de ORDER BY en la subconsulta. Mi mejor opción es la siguiente:

SELECT 
    contacts.first_name, 
    contacts.last_name, 
    (
     SELECT 
      dbo.string_agg(number, ', ') 
     FROM 
      (
       SELECT TOP <some really large number> 
        number 
       FROM 
        phones 
       WHERE 
        phones.contact_id = contacts.id 
       ORDER BY 
        phones.priority 
      ) AS phones 
    ) AS phone_numbers 
FROM 
    contacts 

¿Existe una mejor solución? Y sí, he leído Is order by clause allowed in a subquery, y este es, me atrevería a decir, un caso de uso válido de ORDER BY en la subconsulta.

Respuesta

0

Parece que no hay mejor alternativa que el uso de una subconsulta con TOP <some really large number> de moverse por la limitación de SQL Server:

SELECT 
    contacts.first_name, 
    contacts.last_name, 
    (
     SELECT 
      dbo.string_agg(number, ', ') 
     FROM 
      (
       SELECT TOP <some really large number> 
        number 
       FROM 
        phones 
       WHERE 
        phones.contact_id = contacts.id 
       ORDER BY 
        phones.priority 
      ) AS phones 
    ) AS phone_numbers 
FROM 
    contacts 
0

Su consulta de mejor apuesta no arrojará los resultados que desea. Cuando ORDER BY se utiliza con TOP en una subconsulta como esa, ORDER BY solo se usa para evaluar las condiciones principales. En realidad, no ordena los datos por ti.

+0

he sustituido "TOP 100 por ciento" con "TOP ", y eso parece estar funcionando. – sayap

Cuestiones relacionadas