如何通过时间戳排序从时间戳中获取月份和年份的唯一记录

Posted

技术标签:

【中文标题】如何通过时间戳排序从时间戳中获取月份和年份的唯一记录【英文标题】:How to get unique records with month and year from timestamp with timestamp sorting 【发布时间】:2020-01-18 04:18:59 【问题描述】:
Select Date_format(effective_date, "%M %Y") as time 
from articles 
order by effective_date desc limit 10;
+----------------+                                                 
| time           |                                  
+----------------+                                  
| November 2019  |                                  
| November 2019  |                                  
| September 2019 |                                  
| September 2019 |                                  
| August 2019    |                                  
| July 2019      |                                  
| June 2019      |                                  
| May 2019       |                                  
| April 2019     |                                  
| March 2019     |                                  
+----------------+  

表结构

CREATE TABLE `articles` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `author_id` bigint(20) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `article_page_details_count` int(11) DEFAULT NULL,
  `effective_date` datetime DEFAULT NULL,
  `position` int(11) DEFAULT NULL,
  `hits` int(11) DEFAULT NULL,
  `status` int(11) DEFAULT '0',
  `deleted_at` datetime DEFAULT NULL,
  `created_by_admin_user_id` bigint(20) DEFAULT NULL,
  `updated_by_admin_user_id` bigint(20) DEFAULT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `index_articles_on_author_id` (`author_id`),
  KEY `index_articles_on_created_by_admin_user_id` (`created_by_admin_user_id`),
  KEY `index_articles_on_updated_by_admin_user_id` (`updated_by_admin_user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=113 DEFAULT CHARSET=utf8

我只想获取唯一记录。 distinct 不起作用,如果我使用 group by 则 order 不起作用。

mysql版本是8.0

with Distinct 我得到了错误。

Select distinct(Date_format(effective_date, "%M %Y")) as time 
from articles 
order by effective_date desc limit 10;

ERROR 3065 (HY000): ORDER BY 子句的表达式 #1 不在 SELECT 中 列表,引用列 'articles.effective_date' 不在 选择列表;这与 DISTINCT 不兼容

【问题讨论】:

DISTINCT 将删除重复项,您所说的 不起作用 是什么意思? 发布完整的表格数据和SHOW CREATE TABLE articles ...我假设effective_date不是唯一的列。这里接缝的主要问题是字符串的排序可能会产生不可预测的结果因为字符集/排序规则 请注意,DISTINCT 不是函数。无需使用括号.. 使用这个Select distinct Date_format(effective_date, '%M %Y') @PKP 订单与您的查询不符 【参考方案1】:

我会建议group by,像这样使用order by

select Date_format(effective_date, '%M %Y') as time 
from articles 
group by time
order by min(effective_date) desc
limit 10;

这允许您:

只选择一列 具有独特的价值 按实际日期而非字符串形式排序

【讨论】:

【参考方案2】:

在将DISTINCT 子句与ORDER BY 一起使用时,您需要确保在SELECT 子句中也应选择用于ORDER BY 的字段。

现在,您将日期时间值(Y-m-d h:i:s) 格式转换为(M Y),并使用它进行排序。但它不会给你正确的结果,因为2019-01-01 < 2019-04-01,但是当转换为你的自定义字符串格式时,它会给出January 2019 < April 2019,因为A在char比较中小于J

因此,一种复杂的方法可能是使用 Str_To_Date() 函数将您的自定义“月份年份”字符串重新转换回日期格式 (Y-m-d) 以进行正确排序:

架构 (MySQL v8.0)

create table articles (`effective_date` datetime DEFAULT NULL);

insert into articles values ('2019-01-05');
insert into articles values ('2019-01-06');
insert into articles values ('2019-02-05');

查询 #1

SELECT DISTINCT Date_format(effective_date, "%M %Y") as time_MY 
FROM articles 
ORDER BY STR_TO_DATE(CONCAT(time_MY, ' 1'), '%M %Y %d') desc 
limit 10;

结果

| time_MY       |
| ------------- |
| February 2019 |
| January 2019  |

View on DB Fiddle

【讨论】:

它工作正常。谢谢!你能解释一下这个查询吗?【参考方案3】:

你可能会得到帮助

 Select distinct Date_format(effective_date, "%M %Y") as time 
    from articles 
    order by effective_date desc limit 10;

【讨论】:

【参考方案4】:

这是一个使用GROUP BY的解决方案:

select date_format(effective_date, '%Y %M') new_effective_date
from articles
group by year(effective_date), month(effective_date),  date_format(effective_date, '%Y %M')
order by year(effective_date) desc, month(effective_date) desc
limit 10

Demo on DB Fiddle

with articles as (
      select '2018-01-01' effective_date
      union all select '2018-01-01' 
      union all select '2018-02-01' 
      union all select '2018-03-01' 
 )
select date_format(effective_date, '%Y %M') new_effective_date
from articles
group by year(effective_date), month(effective_date), date_format(effective_date, '%Y %M')
order by year(effective_date) desc, month(effective_date) desc
limit 10;

| new_effective_date |
| ------------------ |
| 2018 March         |
| 2018 February      |
| 2018 January       |

【讨论】:

以上是关于如何通过时间戳排序从时间戳中获取月份和年份的唯一记录的主要内容,如果未能解决你的问题,请参考以下文章

是否有任何独特的 SQL 函数可以从时间戳中仅检索年份和月份,并且基于该结果我需要找出最早制作的

如何使用 pyspark 从 aws 胶水的时间戳中提取年份

从 MYSQL 上的时间戳中提取日/月/年

只想从数据库中的时间戳中保存年份

如何从R中具有月份名称的时间戳中提取日期

如何从 DB2 中的两个时间戳中获取差异?