【问题标题】:Group by the results of a correlated sub-query in SQL 2005按 SQL 2005 中相关子查询的结果分组
【发布时间】:2010-11-17 16:42:09
【问题描述】:

这是我第一次在 Stack Overflow 上发帖,但我已经发现它是非常宝贵的资源。

我的问题与 SQL 语句的 group by 中的相关子查询有关,我知道这是不可能的。我希望通过解释查询的意图,我可以找到一些帮助。以最简单的形式,我尝试按主键进行聚合,并按相关子查询的结果进行分组。用于关联的字段对于每个主键记录都是唯一的。如果我按相关字段分组,它不会提供预期的结果。我需要能够按相关子查询的结果进行分组,但不确定如何重组查询。下面提供了一个示例查询。

谢谢

-约翰

SELECT DISTINCT 
    (SELECT substring(CommaDelimitedTranslatedList, 0, len(CommaDelimitedTranslatedList)) 
    FROM 
        ( 
            SELECT 
                cd.choiceValue + ',' 
            from SelectedChoiceTable sct 
                join ChoiceDescription cd on 
                    cd.ChoiceID = sct.ChoiceID 
            where 
                sct.ChoiceSet = TargetJoinTable.ChoiceKey  FOR XML PATH('')
        ) D ( CommaDelimitedTranslatedList ))  AS           [TargetJoinTableCommaDelimitedTranslatedList1] ,
    count(BaseTable.BaseKey)
 FROM BaseTable
    join TargetJoinTable on 
        BaseTable.BaseKey = TargetJoinTable.BaseKey
Group By 
    [TargetJoinTableCommaDelimitedTranslatedList1]
Order By 
    [TargetJoinTableCommaDelimitedTranslatedList1] ASC

【问题讨论】:

    标签: sql-server-2005 group-by correlated-subquery


    【解决方案1】:

    乍一看,尝试将子查询更改为 CROSS(或 OUTER)APPLY。这会将“列”从 SELECT 子句移动到 FROM 子句,从而允许分组。

    SELECT
        foo.TargetJoinTableCommaDelimitedTranslatedList1 ,
        count(BaseTable.BaseKey)
     FROM
        BaseTable
        join
        TargetJoinTable on BaseTable.BaseKey = TargetJoinTable.BaseKey
        CROSS APPLY
        (
        SELECT
            substring(CommaDelimitedTranslatedList, 0, 2000000000)
                   AS TargetJoinTableCommaDelimitedTranslatedList1
        FROM 
            ( 
            SELECT 
                cd.choiceValue + ',' 
            from
                SelectedChoiceTable sct 
                join
                ChoiceDescription cd on cd.ChoiceID = sct.ChoiceID 
            where 
                sct.ChoiceSet = TargetJoinTable.ChoiceKey
            FOR XML PATH('')
            ) D ( CommaDelimitedTranslatedList )
          ) foo
    Group By 
        foo.TargetJoinTableCommaDelimitedTranslatedList1
    Order By 
        foo.TargetJoinTableCommaDelimitedTranslatedList1 ASC
    

    或者将聚合移出到派生表上

    SELECT
        COUNT(foo.BaseKey),
        TargetJoinTableCommaDelimitedTranslatedList1
    FROM
        (SELECT DISTINCT 
            (SELECT substring(CommaDelimitedTranslatedList, 0, len(CommaDelimitedTranslatedList)) 
            FROM 
                ( 
                    SELECT 
                        cd.choiceValue + ',' 
                    from SelectedChoiceTable sct 
                        join ChoiceDescription cd on 
                            cd.ChoiceID = sct.ChoiceID 
                    where 
                        sct.ChoiceSet = TargetJoinTable.ChoiceKey  FOR XML PATH('')
                ) D ( CommaDelimitedTranslatedList ))  AS           [TargetJoinTableCommaDelimitedTranslatedList1] ,
         BaseTable.BaseKey
    
         FROM BaseTable
            join TargetJoinTable on 
                BaseTable.BaseKey = TargetJoinTable.BaseKey
        ) foo
    Group By 
        [TargetJoinTableCommaDelimitedTranslatedList1]
    Order By 
        [TargetJoinTableCommaDelimitedTranslatedList1] ASC
    

    其中一个问题是 CSV TargetJoinTableCommaDelimitedTranslatedList1 可能会生成很多次:如果我没看错的话,每个 BaseTable.BaseKey 一次。这会很慢。我的感觉是 CSV 生成应该排在最后:您实际上是在 TargetJoinTable.ChoiceKey 上进行分组,而不是它生成的 CSV。

    【讨论】:

    • 我使用了上面的例子。这在我的整体查询中起到了很好的效果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多