【问题标题】:Using ORDER BY on SELECT DISTINCT in TSQL在 SQL 中对 SELECT DISTINCT 使用 ORDER BY
【发布时间】:2009-01-20 22:06:52
【问题描述】:

我正在尝试检索按日期排序的日期字符串列表...

SELECT DISTINCT CONVERT(Varchar(10), GeneratedDate, 101) AS GeneratedDate
FROM dbo.ProviderProcessGeneratedDate
ORDER BY GeneratedDate

这按我将日期转换为的 varchar 排序。

示例...
02/01/2008
2008 年 2 月 15 日
2007 年 2 月 21 日
2007 年 2 月 23 日
2008 年 2 月 29 日

我已经使用内联查询解决了这个问题...

SELECT CONVERT(Varchar(10), a.GeneratedDate, 101) AS GeneratedDate
FROM (SELECT DISTINCT Convert(DATETIME,CONVERT(Varchar(10), GeneratedDate, 101)) AS GeneratedDate
      FROM dbo.ProviderProcessGeneratedDate) a
ORDER BY a.GeneratedDate DESC

为了得到我真正想要的...
2008 年 1 月 11 日
01/04/2008
2007 年 12 月 28 日
2007 年 12 月 21 日

有没有更简单的方法?做这么简单的事情似乎需要做很多工作。

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    您的第一个查询给出的顺序与您想要的不同的原因是...
    - 您使用“GeneratedDate”字段来创建您的字符串
    - 然后将该结果字段别名为“GeneratedDate”
    - 然后您在不指定表格的情况下按“GeneratedDate”排序
    - 所以结果字段被用于排序

    其他答案中提到了简单的修复...

    ORDER BY ProviderProcessGeneratedDate.GenerateDate
    

    通过指定表格没有混淆,你得到你想要的结果。


    [旁白]

    通常,我总是在我的字段前加上 [table]。以避免任何歧义。特别是因为我经常稍后回来并添加一个连接,从而强制表名称使用 ned。

    另外,我给表名起了别名。不是像 [a] 这样的东西,而是像 [Dates] 这样有意义的东西。这缩短了查询,但也允许我更改正在使用的表,而无需在查询的其他部分更改对它的其他引用。

    [旁白结束]

    编辑:

    我以自卑的方式留下了我之前的答案。我真的应该得到一个家庭 sql 服务器,这样我就可以在发布我的答案之前尝试我的答案...... ***道歉*

    正如评论所述,如果 ORDER BY 中没有的内容不在 SELECT DISTINCT 中,则您可能不会在其中指定某些内容。

    因此我会尝试使用 GROUP BY...

    SELECT
        Convert(DATETIME,CONVERT(Varchar(10), GeneratedDate, 101))
    FROM
        ProviderProcessGeneratedDate
    GROUP BY
        GeneratedDate
    ORDER BY
        GeneratedDate
    

    这假设 GeneratedDate 与您的 CONVERT 公式为 1:1。例如,如果您的 GeneratedDate 字段中有 TIME,但 CONVERT 中的日期格式没有;您需要从 GeneratedDate 字段中去掉时间...

    SELECT
        Convert(DATETIME,CONVERT(Varchar(10), DATEADD(DAY, DATEDIFF(DAY, 0, GeneratedDate), 0), 101))
    FROM
        ProviderProcessGeneratedDate
    GROUP BY
        DATEADD(DAY, DATEDIFF(DAY, 0, GeneratedDate), 0)
    ORDER BY
        DATEADD(DAY, DATEDIFF(DAY, 0, GeneratedDate), 0)
    

    【讨论】:

    • 指定表名也不起作用:SELECT DISTINCT CONVERT(Varchar(10), GeneratedDate, 101) AS GeneratedDatex FROM dbo.ProviderProcessGeneratedDate ORDER BY ProviderProcessGeneratedDate.GeneratedDate /*error: ORDER BY 项目必须出现在如果指定了 SELECT DISTINCT,则选择列表。 */
    【解决方案2】:

    只是添加到上面的答案......

    您可以在 tsql 之外转换回字符串。只需返回 datetime 类型并在代码中转换为您想要的日期格式(显示层)。

    【讨论】:

      【解决方案3】:
        SELECT DISTINCT Convert(DATETIME,CONVERT(Varchar(10), GeneratedDate, 101)) 
                           AS GeneratedDate,
              A.GeneratedDate OrderByDate       
        FROM dbo.ProviderProcessGeneratedDate A
        Order By A.GeneratedDate Desc
      

      【讨论】:

      • 问题是我想按不同于 select distinct 子句中的内容进行排序。所以它不会让我。 SELECT DISTINCT CONVERT(Varchar(10), GeneratedDate, 101) 它给出了这个错误...如果指定了 SELECT DISTINCT,则 ORDER BY 项必须出现在选择列表中。
      • 是的,这就是我在 select 子句中添加 A.GeneratedDate 的原因
      • 它不需要在 select 子句中,您只需要明确订购的内容。 (您在 ORDER BY 子句中使用了“A.”前缀,但提问者没有……)
      • 我的错,我很烂。我可以删除评论,还是我现在必须看起来像个白痴? :) (Dems 学会了下次先尝试他的答案)
      【解决方案4】:

      如果您使用的是 SQL 2005 或 2008,也可以使用 CTE。

      您的代码如下所示:

      WITH Dates(GeneratedDate) AS
      (
      SELECT DISTINCT CONVERT(Varchar(10), GeneratedDate, 101) AS GeneratedDate
      FROM dbo.ProviderProcessGeneratedDate
      )
      
      SELECT GeneratedDate FROM Dates ORDER BY GeneratedDate
      

      【讨论】:

        【解决方案5】:

        我认为你可以使用:

        ORDER BY dbo.ProviderProcessGeneratedDate.GeneratedDate
        

        强制它使用原始表中的值,而不是新修改的值?您甚至可以为 FROM 子句添加别名:

        FROM dbo.ProviderProcessGeneratedDate ppgd
        

        这样您就可以在我的第一条语句中使用“ppgd”别名而不是整个表名。

        【讨论】:

        • 我不能因为...如果指定了 SELECT DISTINCT,则 ORDER BY 项目必须出现在选择列表中。
        【解决方案6】:

        也许您只需要使用另一个字段别名,以便它使用日期而不是格式化字符串?即

        SELECT DISTINCT CONVERT(Varchar(10), GeneratedDate, 101) AS GeneratedDateString
        FROM dbo.ProviderProcessGeneratedDate
        ORDER BY GeneratedDate
        

        尽管在大多数情况下,您确实应该将日期保留为日期,并在可能的最后一刻在 UI 中进行任何所需的格式设置。

        【讨论】:

        • 不要使用不同的别名,而是在 ORDER BY 子句中指定表 (ProviderProcessGeneratedDate.GeneratedDate)
        【解决方案7】:

        修改原始语句的 ORDER BY 以使用可排序的日期字符串:

        SELECT DISTINCT CONVERT(Varchar(10), GeneratedDate, 101) AS GeneratedDate
        FROM dbo.ProviderProcessGeneratedDate
        ORDER BY CONVERT(Varchar(10), GeneratedDate, 112) 
        

        【讨论】:

          【解决方案8】:

          使用GROUP BY 代替DISTINCT

          SELECT 
              CONVERT(Varchar(10), GeneratedDate, 101) AS GeneratedDate
          FROM 
              dbo.ProviderProcessGeneratedDate AS BaseDates
          GROUP BY 
              BaseDates.GeneratedDate, 
              CONVERT(Varchar(10), GeneratedDate, 101)
          ORDER BY 
              BaseDates.GeneratedDate
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-09
            相关资源
            最近更新 更多