SQL 服务器 Select 使用 CASE 区分和排序

SQL Server Select Distinct and Order By with CASE

我看过很多关于这种情况的 questions/forum 帖子,但我要么不理解解决方案,要么所提供的解决方案对那个特定问题过于具体,我不知道如何应用它对我的情况。我有以下查询:

SELECT DISTINCT d.*
FROM Data d
JOIN Customers c 
ON c.Customer_Name = d.Customer_Name
AND c.subMarket = d.subMarket
JOIN Sort s 
ON s.Market = c.Market
ORDER BY d.Customer_Name, d.Category, d.Tab, d.SubMarket,
CASE s.sortBy
WHEN 'Comp_Rank'
THEN d.Comp_Rank
WHEN 'Market_Rank'
THEN d.Market_Rank
ELSE d.Other_Rank
END

我在我的 MySQL 数据库上使用了那个精确的查询,它运行得很好。我们最近切换到 SQL 服务器数据库,但现在它不起作用,我收到错误消息:

ORDER BY items must appear in the select list if SELECT DISTINCT is specified.

我尝试将 s.* 添加到 SELECT(因为 s.sortBy 在 CASE 中)并且没有改变任何东西,我也尝试列出SELECT 中数据和排序中的每个字段都导致了完全相同的错误。

数据中实际上没有重复项,但是当我执行联接时,它会为每个项目生成 4 个完全重复的行,我不知道如何解决这个问题,所以这就是我最初添加 DISTINCT 的原因。我尝试了 LEFT JOIN、INNER JOIN 等的变体……但无法得到不同的结果。无论如何,任何一个问题的解决方案都可以,但我假设需要更多信息才能找出 JOIN 重复问题。

编辑:我刚刚意识到我错误地输入了 ORDER BY 中的一些字段(例如,n.Category、n.Tab 应该是 d.Category、d.Tab ). ORDER BY 中的所有内容都来自我从中选择 * 的数据 table。正如我所说,我也尝试列出 SELECT 中的每个字段,但没有帮助。

如错误所示,当您使用 select distinct 时,您必须按 select 子句中的表达式排序。因此,您的 case 以及所有非 d.

的列都是一个问题

您可以改用 group by 并包括您要作为排序依据的列来解决此问题。因为案例包含来自 s 的列,您需要在 group by:

中包含 case(或至少该列)
SELECT d.*
FROM Data d JOIN
     Customers c 
     ON c.Customer_Name = d.Customer_Name AND
        c.subMarket = d.subMarket JOIN Sort s 
     ON s.Market = c.Market
GROUP BY "d.*",
         (CASE s.sortBy WHEN 'Comp_Rank' THEN d.Comp_Rank
                        WHEN 'Market_Rank' THEN d.Market_Rank
                        ELSE d.Other_Rank
         END)
ORDER BY d.Customer_Name, d.Category, d.Tab, d.SubMarket,
         (CASE s.sortBy WHEN 'Comp_Rank' THEN d.Comp_Rank
                        WHEN 'Market_Rank' THEN d.Market_Rank
                        ELSE d.Other_Rank
         END)

请注意 "d.*" 在引号中。您需要列出 group by.

中的所有列

试试这个:

SELECT DISTINCT d.Customer_Name, d.Category, d.Tab, d.SubMarket,
  CASE s.sortBy
    WHEN 'Comp_Rank'
      THEN d.Comp_Rank
    WHEN 'Market_Rank'
      THEN d.Market_Rank
    ELSE
      d.Other_Rank
  END

FROM Data d

JOIN Customers c 
  ON c.Customer_Name = d.Customer_Name
 AND c.subMarket = d.subMarket

JOIN Sort s 
  ON s.Market = c.Market

ORDER BY d.Customer_Name, d.Category, d.Tab, d.SubMarket,
  CASE s.sortBy
    WHEN 'Comp_Rank'
      THEN d.Comp_Rank
    WHEN 'Market_Rank'
      THEN d.Market_Rank
    ELSE
      d.Other_Rank
  END

为了跟进此事,您只需要使用 AS 将案例添加到您的 SELECT。然后将该引用包含在 ORDER BY 列表中。

SELECT DISTINCT d.*, case when ... then ... else ... end AS MyCase
...
ORDER BY d.Customer_Name, d.Category, d.Tab, d.SubMarket, MyCase

这个答案与 Pang 的相似,但我发现不必在顶部和底部都包含 case 语句更好,因为如果您修改一个而不修改另一个,可能会出现错误。