【问题标题】:SQL Server Select Distinct and Order By with CASESQL Server 使用 CASE 选择 Distinct 和 Order By
【发布时间】:2015-02-26 00:26:10
【问题描述】:

我已经看到很多关于这种情况的问题/论坛帖子,但我要么不理解解决方案,要么提供的解决方案过于针对该特定问题,我不知道如何将其应用于我的情况.我有以下查询:

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 Server 数据库,但现在它不起作用,我收到错误:

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

我尝试将 s.* 添加到 SELECT 中(因为 s.sortBy 在 CASE 中)并且没有改变任何内容,我还尝试在 SELECT 中列出 Data 和 Sort 中的每个字段和这导致了同样的错误。

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

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

【问题讨论】:

  • distinct 与sql server 一起使用时,您必须将order by 子句中的所有字段添加到select 语句中。在这种情况下,您需要添加类别、标签、子市场和您的案例陈述。

标签: sql sql-order-by case distinct


【解决方案1】:

正如错误提示,当您使用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 中的所有列。

【讨论】:

  • 嗨,对不起,我刚刚意识到我在原来的帖子中犯了一个错误。我进行了编辑和解释。基本上,ORDER BY 中的所有内容都来自我从中选择所有内容的数据表。我不会按您所说的不寻常的 select 语句中没有的任何内容进行排序。
  • 完美运行(根据我的编辑进行调整后)。谢谢!
【解决方案2】:

试试这个:

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

【讨论】:

    【解决方案3】:

    只是为了跟进这一点,您只需使用 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 语句会更好,因为如果您修改了一个而不是另一个,则可能会出现错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-16
      • 1970-01-01
      相关资源
      最近更新 更多