【问题标题】:SQL - One record per dateSQL - 每个日期一条记录
【发布时间】:2012-08-07 05:59:44
【问题描述】:

现在我有以下数据:

        Name          Time

       picture  2012-07-23 17:00:00
       picture  2012-07-24 18:00:00
       picture  2012-07-24 19:00:00
       picture  2012-08-03 08:40:06
       picture  2012-08-03 08:42:39
       picture  2012-08-03 08:54:03
       picture  2012-08-03 10:38:58
       picture  2012-08-03 10:39:55
       picture  2012-08-06 08:12:14

还有以下 SQL 查询:

    SELECT DATE_FORMAT(DATE(DATE_SUB(time,INTERVAL 4 HOUR)),GET_FORMAT(DATE,'ISO'))
    as time, uri, media_id, description
    FROM media WHERE place_id = 1 
    GROUP BY time ORDER BY time DESC 

效果很好,并为我提供了我想要的数据。 但是每个唯一日期的数据按每个“天”中最旧的日期排序。我希望它按最新订购。 Order By 语句只是对整个结果进行排序,而不是每一天的日期。如果 o 在使用 Group By 时可以采用最新的日期而不是最旧的日期,但我想我必须解决除 group by 之外的其他问题。

编辑:以下工作。但是我想从子查询中返回更多的列,我该怎么做?

    SELECT Distinct DATE_FORMAT( DATE( DATE_SUB(time, INTERVAL 4 HOUR ) ) ,
    GET_FORMAT( DATE,  'ISO' ) ) AS date, 
            (SELECT type FROM media WHERE 
            DATE_FORMAT( DATE( DATE_SUB(time, INTERVAL 4 HOUR ) ) ,
           GET_FORMAT( DATE,'ISO' ) )  = date Order by time DESC Limit 1) as name
    FROM media

【问题讨论】:

  • 按时间 DESC 分组?按时间 DESC 排序?
  • 问题是Group By不是排序功能。所以它没有区别。我想我需要一个子查询。
  • 我的错。 MySQL 文档似乎暗示您可以做到这一点。即,在此页面上:dev.mysql.com/doc/refman/5.0/en/select.html ... 所以如果它不这样做,我会对 ASC|DESC 与 group by 一起使用时的用途感兴趣
  • 如果我 SELECT Distinct DATE_FORMAT(DATE(DATE_SUB(time,INTERVAL 4 HOUR)),GET_FORMAT(DATE,'ISO')) as date FROM media WHERE place_id = 1 然后我得到所有日期.也许只需向该查询添加一个子查询,该查询从每个日期的最新信息中获取信息。

标签: mysql sql sql-order-by group-by


【解决方案1】:

使用子查询返回每天的最大时间:

SELECT  MAX(Time) AS Time
FROM    Media
WHERE   Place_ID = 1
GROUP BY CAST(Time AS DATE)

然后将其加入您的媒体表,将结果限制为每天一个:

SELECT  Type AS Name,
        DATE_FORMAT(DATE(DATE_SUB(Media.time, INTERVAL 4 HOUR)), GET_FORMAT(DATE, 'ISO')) AS Time,
        uri, 
        media_id, 
        description
FROM    Media
        INNER JOIN
        (   SELECT  MAX(Time) AS Time
            FROM    Media
            WHERE   Place_ID = 1
            GROUP BY CAST(Time AS DATE)
        ) MaxTime
            ON MaxTime.Time = Media.Time;

此解决方案的一个巨大好处是主体适用于所有 DBMS,而目前 MySQL 是我所知道的唯一支持 select 语句中不属于聚合函数或包含在 group by 中的列陈述。我最近写了another answer on SO,描述了这个功能在 MySQL 中的潜在危害,以及为什么其他 DMBS 还不支持它。

Example on SQLFiddle

【讨论】:

  • 哇!谢谢!它工作得很好。我有一个自己的解决方案,它为每一列做了一个子查询。它有效,但效率不高。您的解决方案要好得多:)
【解决方案2】:

将此“GROUP BY time ORDER BY time DES*C”更改为“*GROUP BY DATE ORDER BY time DATE”。它会将数据从新日期缩短到旧日期。

【讨论】:

    【解决方案3】:

    用子字符串稍微分解您的语句,以便您在 TIME 和 DATE 上都有 ORDER BY。像这样的东西应该可以工作;

    SELECT DATE_FORMAT(DATE(DATE_SUB(time,INTERVAL 4 HOUR)),GET_FORMAT(DATE,'ISO')) 
    as time, uri, media_id, description 
    FROM media WHERE place_id = 1  
    GROUP BY time ORDER BY SUBSTRING(time,1,10) DESC, SUBSTRING(time,12,8) ASC
    

    【讨论】:

    • 我不清楚你的桌子上有哪些独特的列,但如果 DATE 和 TIME 是单独的值,那么你为什么不能尝试调整你的语句来执行 'ORDER BY DATE DESC, TIME ASC'
    • 您尝试过我在原始查询中建议的 SUBSTRING 吗?
    • 按时间分组,因此不会为每个日期返回唯一的结果,而是返回按日期排序的所有项目。 As shown on SQLFiddle。我假设您正在尝试使用 group by 中的别名 time 在选择列表中引用您的列,如果是这样,您需要给它一个不同的别名以避免歧义 e.g. Time2
    【解决方案4】:

    试试这个:

      SELECT time,DATE_FORMAT(DATE(DATE_SUB(time,INTERVAL 4 HOUR)),
             GET_FORMAT(DATE,'ISO')) as date, uri, media_id, description
      FROM media WHERE place_id = 1 
      ORDER BY date DESC ,time desc
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多