2011-04-26 23 views
5

在PostgreSQL,有这个非常有用的功能string_agg,允许查询,如:移植PostgreSQL的string_agg到SQL Server,问题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 

同样,这在MySQL中可使用进行GROUP_CONCAT。

现在,我试图将此端口移植到SQL Server中作为CLR用户定义的聚合。代码本身并不是问题,因为全网上有成千上万的例子来创建这个特定的聚合(它提出了一个问题:为什么它不是SQL Server的一部分呢?)。

问题是,我找不到一个干净的方式来应用ORDER BY,因为SQL Server不仅不支持聚合函数中的ORDER BY,还禁止在子查询中使用ORDER BY。我最好的选择是这样的:

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 

有没有更好的解决方法?是的,我已阅读Is order by clause allowed in a subquery,这是,我敢说,在子查询中一个有效的ORDER BY用例。

回答

0

貌似没有比使用与TOP <some really large number>子查询得到解决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

你最好的赌注查询不会返回你想要的结果。当在这样的子查询中将ORDER BY与TOP一起使用时,ORDER BY仅用于评估顶级条件。它并不实际为您订购数据。

+0

我已经取代了“TOP 100%”和“TOP <一些真正大量>”,并这似乎工作。 – sayap 2011-04-26 06:41:48