SQL Server:将GROUP BY与CASE一起使用后,ORDER BY不起作用

时间:2018-03-22 21:16:26

标签: sql-server tsql

考虑以下T-SQL查询。我在CASESELECT中使用GROUP BY将两个人的记录合并为一个,因为它实际上是同一个人。在这个例子中,我已将名称更改为'PersonX'。

SELECT 
    COUNT(DISTINCT d.PONum) AS POCount, 
    ISNULL(SUM(d.DocExtCost), 0) AS POValue, 
    CASE v.Buyer_c          
       WHEN 'Person5' 
          THEN 'Person4'    
          ELSE v.Buyer_c                    
    END AS BuyerID
FROM 
    [Dbo].PODetail AS d       
INNER JOIN 
    [Dbo].Vendor AS v ON (d.Company = v.Company AND d.VendorNum = v.VendorNum)
WHERE 
    v.Buyer_c IN ('Person1', 'Person2', 'Person3', 'Person4', 'Person5')
GROUP BY 
    CASE v.Buyer_c 
       WHEN 'Person5' 
          THEN 'Person4'    
          ELSE v.Buyer_c 
    END
ORDER BY 
    v.Buyer_c   <-- This order by doesn't work

没有订单的结果:

enter image description here

当我尝试使用订单时,我收到此错误:

  

“Dbo.Vendor.Buyer_c”列在ORDER BY子句中无效,因为它不包含在聚合函数或GROUP BY子句中。

我不知道在哪里添加v.Buyer_c,它已经在GROUP BY语句的CASE子句中。如果我再次添加它,就像这样:

GROUP BY 
    CASE v.Buyer_c 
       WHEN 'Person5' 
          THEN 'Person4'    
          ELSE v.Buyer_c 
    END, 
    v.Buyer_c

它正确地停止分组并为Person4和amp;提供两个不同的记录。 Person5。

我想使用订单,所以我可以按字母顺序订购记录。如何使用buyerID按字母顺序订购记录?

3 个答案:

答案 0 :(得分:2)

你放order by BuyerID并检查

答案 1 :(得分:2)

您必须使用与

相同的逻辑
SELECT COUNT(DISTINCT d.PONum) AS POCount, 
   ISNULL(SUM(d.DocExtCost), 0) AS POValue, 
   CASE v.Buyer_c           
        WHEN 'Person5' THEN 'Person4'   
        ELSE v.Buyer_c                  
   END AS BuyerID

FROM [Dbo].PODetail AS d       

INNER JOIN [Dbo].Vendor AS v
    ON (d.Company = v.Company AND
        d.VendorNum = v.VendorNum)

WHERE v.Buyer_c IN ('Person1', 'Person2', 'Person3', 'Person4', 'Person5')

GROUP BY CASE v.Buyer_c 
        WHEN 'Person5' THEN 'Person4'   
        ELSE v.Buyer_c 
     END

ORDER BY CASE v.Buyer_c 
        WHEN 'Person5' THEN 'Person4'   
        ELSE v.Buyer_c 
     END

答案 2 :(得分:1)

这是一种方法:

with cte as 
(
    select count(distinct d.ponum) as pocount, 
        isnull(sum(d.docextcost), 0) as povalue, 
        case v.buyer_c           
            when 'person5' then 'person4'   
            else v.buyer_c                  
        end as buyerid
    from [dbo].podetail as d       
    inner join [dbo].vendor as v on (d.company = v.company and d.vendornum = v.vendornum)
    where v.buyer_c in ('person1', 'person2', 'person3', 'person4', 'person5')      
    group by case v.buyer_c 
            when 'person5' then 'person4'   
            else v.buyer_c 
            end
)
select *
from cte
order by buyerid