【问题标题】:Access direct column value in ORDER BY clause访问 ORDER BY 子句中的直接列值
【发布时间】:2011-09-16 10:48:28
【问题描述】:

我刚刚在一些代码中发现了一个错误。有一个类似这样的SQL:

SELECT convert(varchar(11),COL1,106) as COL1
FROM TAB
ORDER BY COL1 DESC

现在,返回的 COL1 值格式如下所示:

17 Sep 2001
07 Mar 2011

存储在数据库中的值如下所示:

2011-03-07 00:00:00
2001-09-17 00:00:00

但是因为 ORDER BY 子句使用了

17 Sep 2001
07 Mar 2011

值,排序不正确。由于我无法更改列名(查询和使用它的应用程序之间存在很大的依赖关系),我必须修改和修复 SQL 语句以返回具有正确顺序的行。有没有办法以 ORDER BY 子句使用存储在行列中的实际值而不是转换的方式来修改它?我试过了:

ORDER BY TAB.COL1 DESC

但它也没有工作。

谢谢,帕维尔

【问题讨论】:

    标签: sql sql-server tsql sql-server-2000


    【解决方案1】:

    您可以将字段的别名更改为 COL1 以外的其他名称,这应该会导致 ORDER BY 继续在字段本身而不是计算的别名上:

    SELECT convert(varchar(11),COL1,106) as COL1_ALIAS
    FROM TAB
    ORDER BY COL1 DESC
    

    更新

    如果列名需要保持不变,试试这个:

    SELECT convert(varchar(11),COL1,106) as COL1, COL1 AS COL1_ORIGINAL
    FROM TAB
    ORDER BY COL1_ORIGINAL DESC
    

    【讨论】:

    • 我无法更改它,因为使用该查询的应用程序适用于列名,因此必须保留 COL1
    • +1 第二个查询看起来不错:无论如何向调用者公开排序顺序列是一个好习惯。
    【解决方案2】:

    你应该用表名来限定你的列名

    ORDER BY TAB.COL1 DESC
    

    试试这个

    create table TAB(Col1 datetime)
    
    insert into TAB values (getdate())
    insert into TAB values (getdate()+323)
    
    SELECT convert(varchar(11),COL1,106) as COL1
    FROM TAB
    ORDER BY TAB.COL1 DESC
    
    SELECT convert(varchar(11),COL1,106) as COL1
    FROM TAB
    ORDER BY COL1 DESC
    

    SQL Server 2008 和 SQL Server 2005 上的结果:

    COL1
    -----------
    04 Aug 2012
    16 Sep 2011
    
    (2 row(s) affected)
    
    COL1
    -----------
    16 Sep 2011
    04 Aug 2012
    
    (2 row(s) affected)
    

    这不适用于 SQL Server 2000,因此如果您确实需要列名与别名相同,这里有一个解决方法。

    SELECT convert(varchar(11),COL1,106) as COL1
    FROM TAB
    ORDER BY convert(datetime, COL1) DESC
    

    编辑 如果您具有兼容级别 SQL Server 2000(80),它也不会在更高版本的 SQL Server 中工作。在这种情况下,我建议您更改兼容性级别。

    【讨论】:

    【解决方案3】:

    如果你想在转换值之前进行排序,那么试试这个:

    SELECT  CONVERT(VARCHAR(11),COL1,106) as COL1 
    FROM        TAB 
    ORDER BY    COL1 DESC
    

    或者如果你想在转换值后进行排序,那么试试这个:

    SELECT convert(varchar(11),COL1,106) as COL1 
    FROM TAB 
    ORDER BY convert(varchar(11),COL1,106) DESC 
    

    【讨论】:

    • 操作想要按原始值排序,而不是我认为的转换值
    • 您的想法很好,我已将格式代码更改为 120(以可排序格式返回日期)。 Now 子句如下所示: ORDER BY CONVERT(nvarchar(11), COL, 120) DESC ,结果如我所料。谢谢
    • 如果您的第一个查询在没有派生表名称且在子查询中使用 ORDER BY 的情况下确实可以正常工作,但在受支持的 SQL Server 版本中肯定无法正常工作,我感到很惊讶。
    • @onedaywhen :现在检查我的答案。我认为不需要子查询来按原始列排序
    • 好的,与此同时,我在 MSSQL2000 服务器上进行了测试,并且 ORDER BY 确实导致了错误,因此将其编辑掉是正确的;)
    【解决方案4】:

    你可以试试这样的:

    SELECT  convert(varchar(11),COL1,106) as COL1
    FROM    (SELECT      COL1
             FROM        TAB
             ORDER BY    COL1 DESC)
    

    这基本上会在将结果放入转换方法之前对其进行排序。

    【讨论】:

      【解决方案5】:

      双重重命名:

      SELECT convert(varchar(11), COLX, 106) AS COL1
      FROM  
           ( SELECT COL1 AS COLX
             FROM TAB
           ) tmp
      ORDER BY COLX DESC
      

      【讨论】:

        猜你喜欢
        • 2011-10-12
        • 2010-09-18
        • 1970-01-01
        • 2017-12-07
        • 1970-01-01
        • 2011-09-07
        • 2018-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多