【问题标题】:SQL order within cases, DESC and ASC odd behavior案例中的 SQL 顺序,DESC 和 ASC 奇怪的行为
【发布时间】:2014-03-22 12:12:16
【问题描述】:

我很难让这条 SQL 语句产生我想要的结果。这是我正在使用的代码:

SELECT * FROM "Contracts" WHERE "productType" = 'RINbuy' AND "clearTime" IS NULL order by case when "holdTime" is not null then 0 else 1 end, case when "holdTime" is not null then "generationTime" else "contractLimitPrice" end;

我正在尝试获得类似这样的结果

+---------------+----------+--------------------+ |generationTime | holdTime | contractLimitPrice | +---------------+----------+--------------------+ | 1 |5 | 1.282 | | 4 |6 | 1.535 | | 2 |NULL | 1.911 | | 3 |NULL | 1.764 | +---------------+----------+--------------------+

但我明白了:

+---------------+----------+--------------------+ |generationTime | holdTime | contractLimitPrice | +---------------+----------+--------------------+ | 1 |5 | 1.282 | | 4 |6 | 1.535 | | 3 |NULL | 1.764 | | 2 |NULL | 1.911 | +---------------+----------+--------------------+ 最后两行交换。我尝试在每个可能的排列中添加 DESC 和 ASC 以及交换 0 和 1。我还尝试切换 case 语句的顺序。
编辑: 我的最终目标是,如果holdTime 不为NULL,则按generationTime 对表进行排序,如果holdTime 为NULL,则按contractLimitPrice 对DESC 进行排序。

【问题讨论】:

  • 您能否发布两种情况的输出:(1)在最后一个分号之前添加 DESC; (2) 在第二个case语句的字段名的引号内加上DESC,如generationTime DESC
  • @ChrisJohnson 案例(1):底部的 2 行是正确的行,但顶部的两行是翻转的。案例(2):当我将 DESC 放在引号ERROR: column "generationTime DESC" does not exist LINE 6: case when "holdTime" is not null then "generationTime DESC... 中时出现错误
  • 该示例并未阐明所有可能的情况。

标签: sql database postgresql


【解决方案1】:

再看一遍:单个 CASE 语句无法达到您的预期!好像你想用"holdTime" IS NULL"contractLimitPrice" 对行进行排序,其余的按"generationTime" 排序。
如果是这样,请改用它:

ORDER BY "holdTime" IS NULL
       , CASE WHEN "holdTime" IS NULL THEN "contractLimitPrice" END DESC
       , CASE WHEN "holdTime" IS NULL THEN NULL ELSE "generationTime" END

"holdTime" IS NULL ... FALSE (0) 排在 TRUE (1) 之前。

这也减轻了类型转换可能引起的任何问题。

第二项末尾的DESC 来自您的评论。您的问题不清楚。

对于您的原始版本:
CASE 语句仅适用于相同类型的列(或可以自动转换的类型。您没有透露您的实际数据类型。无论哪种方式,如果类型不相同,您将转换为更精确的类型。

错误信息:

> ERROR: column "generationTime DESC" does not exist LINE 6:

指向一个简单的语法错误,它在您的查询中不是

【讨论】:

  • 每列的数据类型为double。我尝试了您建议的两段代码。两者都产生了与我的代码相同的结果。当holdTime为NULL时,我需要弄清楚如何获得合约限价以对DESC进行排序。
【解决方案2】:

问题在于数据类型。一个值是日期,另一个是数字(或字符)。因此,结果正在被隐式转换。

你可以这样做:

order by (case when "holdTime" is not null then 0 else 1 end),
         (case when "holdTime" is not null then "generationTime" end),
         (case when "holdtime" is null then "contractLimitPrice" end)

您不必担心当第二个和第三个条件不成立时会产生额外的NULL 值。第一个条件确保基于有效holdtime 的组一起出现。

编辑:

你试过了吗?

order by (case when "holdTime" is not null then 0 else 1 end),
         (case when "holdTime" is not null then  "generationTime"
               else "contractLimitPrice" 
          end) desc;

只有两个值,很难准确判断发生了什么。但看起来它们是按升序排序的。

【讨论】:

  • 出于问题的目的,我将日期更改为人类可读的日期。时间存储为unix时间,存储为double,contractLimitPrice也存储为double。无论如何我尝试了你的建议,我得到了相同的输出。抱歉没有输入“真实”值,我将编辑我的 OP。
猜你喜欢
  • 1970-01-01
  • 2016-12-25
  • 1970-01-01
  • 2013-04-13
  • 2020-09-12
  • 1970-01-01
  • 2021-09-21
  • 2010-12-14
  • 1970-01-01
相关资源
最近更新 更多