sql - 如何对列表聚合进行排序?

标签 sql firebird firebird2.5

在下面的查询中,我想要等效的

GROUP_CONCAT(ctAncestors.ancestor ORDER BY ctAncestors.depth DESC) AS breadcrumbs_id 

在 Firebird 中。

到目前为止我已经得到了

LIST(ctAncestors.ancestor, ',') AS breadcrumbs_id 

我不知道如何在列表指令中添加订单。

如何在列表聚合中进行排序?

-- http://www.unlimitedtricks.com/sorting-a-subtree-in-a-closure-table-hierarchical-data-structure/

-- DECLARE @__in_rootnodeId AS bigint 
-- SET @__in_rootnodeId = 8 
-- SET @__in_rootnodeId = 1 


SELECT 
     COALESCE(ctDescendants.ancestor, 0) AS parent_id 
    ,ctAncestors.descendant AS child_id 
    ,tClosureItemsTable.COM_Id 
    ,tClosureItemsTable.COM_Text 

--,'ab' as breadcrumbs
 
--,LIST(ctAncestors.ancestor ORDER BY ctAncestors.depth DESC) AS breadcrumbs_id 
,LIST(ctAncestors.ancestor, ',') AS breadcrumbs_id 
    --,GROUP_CONCAT(ctAncestors.ancestor ORDER BY ctAncestors.depth DESC) AS breadcrumbs_id 
    -- ,GROUP_CONCAT(breadcrumb_data.COM_Text ORDER BY ctAncestors.depth DESC) AS breadcrumbs 
--,GROUP_CONCAT(breadcrumb_data.COM_Text ORDER BY ctAncestors.depth) AS breadcrumbs 
,LIST(breadcrumb_data.COM_Text) AS breadcrumbs 
--,GROUP_CONCAT(breadcrumb_data.COM_Text ORDER BY ctAncestors.depth DESC SEPARATOR '-') AS breadcrumbs2 




/*  
,
    SUBSTRING
    (
        (
            SELECT 
                -- breadcrumb.ancestor AS 'text()'  -- Remove substring for this 
                -- ', ' + CAST(breadcrumb.ancestor AS nvarchar(36)) AS 'text()'
                ', ' + CAST(breadcrumb_data.comment AS nvarchar(36)) AS 'text()'
            FROM T_CommentClosure AS breadcrumb 
            
            LEFT JOIN Comments AS breadcrumb_data
                ON breadcrumb_data.COM_Id = breadcrumb.ancestor

            WHERE (breadcrumb.descendant = ctAncestors.descendant) 

            ORDER BY breadcrumb.depth DESC
            FOR XML PATH('')
        )
        ,2
        ,8000
    ) AS breadcrumbs 
*/  

    ,
    (
        SELECT COUNT(*) FROM T_CommentClosure AS tp 
        WHERE tp.ancestor = tClosureItemsTable.COM_Id AND tp.depth = 1 
    ) AS ChildCount 

FROM T_CommentClosure AS ctAncestors  

-- Must be left join, for root node
LEFT JOIN T_CommentClosure AS ctDescendants 
    ON (ctDescendants.descendant = ctAncestors.descendant) 
    AND (ctDescendants.depth = 1) 

-- INNER JOIN just in case item has been somehow deleted when FK disabled 
INNER JOIN T_Comments AS tClosureItemsTable  
    ON (ctAncestors.descendant = tClosureItemsTable.COM_Id) 
    
INNER JOIN T_Comments AS breadcrumb_data
    ON breadcrumb_data.COM_Id = ctAncestors.ancestor 
    
WHERE (1=1) 
-- AND (ctAncestors.ancestor = @__in_rootnodeId) -- ROOT node id 
AND 
( 
    -- ( ctAncestors.ancestor = @__in_rootnodeId) -- ROOT node id 
    (1=2) 
    OR 
    (1=1)
--    (@__in_rootnodeId IS NULL) 
) 

-- AND tClosureItemsTable.active = 1 

GROUP BY 
     ctAncestors.descendant 
    ,ctDescendants.ancestor 
    ,tClosureItemsTable.COM_Id 
    ,tClosureItemsTable.COM_Text 

ORDER BY breadcrumbs ASC  -- DESC

最佳答案

作为 LIST() 的文档状态:

The ordering of the list values is undefined.

也就是说,如果您使用首先按 GROUP BY 列和此列进行排序的子查询或公共(public)表表达式 (CTE),那么它将起作用,但这确实意味着您依赖于可能会随着点发布或新版本而改变的实现工件。

Firebird 跟踪器中有一个针对此问题的改进票 ( CORE-2332 ),但尚未计划发布版本。此票证还包含解决方法的示例:

WITH EDU_EPT AS (
  SELECT EEPT2.TARGET_SWE
  FROM EDUCATION_EVENT_PR_TRGT EEPT2
  WHERE EEPT2.EDUCATION_EVENT_ID = :EDU_EVENT_ID
  ORDER BY EEPT2.ORDINAL, EEPT2.ID
)
SELECT LIST('• ' || EEPT.TARGET_SWE, ASCII_CHAR(13) || ASCII_CHAR(10)) || '.'
FROM EDU_EPT EEPT 

关于sql - 如何对列表聚合进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17253193/

相关文章:

printing - 如何打印 Firebird 触发器?

delphi - 如何在不使用存储过程的情况下使用 dbExpress 框架更改生成器值?

自治事务中的 Firebird 2.5 异常处理

sql - 修复 SQL 中的重复客户

sql - 带有 OUTPUT 参数的 T-SQL 存储过程出错

php - MySQLi 在 PHP 中准备更新语句

sql - 如何在彼此下方返回两个查询的结果

Firebird 2.5 错误, "ReadFile"文件操作期间出现 I/O 错误

sql - 更改 Firebird 数据库和表的默认排序规则

PHP学院教程-查询方法