mysql 日期排序查询,就是有张表,但是表的时间不全,但是我想没有数据的日期也查出来,怎么搞?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql 日期排序查询,就是有张表,但是表的时间不全,但是我想没有数据的日期也查出来,怎么搞?相关的知识,希望对你有一定的参考价值。

其实你把需要的日期写在一个数组。然后mysql查出来的数据按照日期存进数组里 这样不是没数据的日期也有了。追问

但是这些数据都是动态的啊?

参考技术A 这个表 有id不,用id查 如果 你的 时间是,按照id查出来数据就应该是你添加的时间的倒序 参考技术B

使用   IFNULL   函数,  不知道能否满足你的需求

 

用法是

 

IFNULL  (   数据库里面的日期列,       ' 如果数据库里面的日期为空,那么所使用的默认值 '   )

mysql> create table test1(
    ->     id  int,
    ->  test_dt  date
    -> );
Query OK, 0 rows affected (0.06 sec)

  
mysql> insert into test1 values(1, '2014-06-17');
Query OK, 1 row affected (0.03 sec)

  
mysql> insert into test1 values(2, NULL);
Query OK, 1 row affected (0.02 sec)

  
mysql> insert into test1 values(3, '2014-07-01');
Query OK, 1 row affected (0.02 sec)

  
mysql> SELECT * FROM test1;
+------+------------+
| id   | test_dt    |
+------+------------+
|    1 | 2014-06-17 |
|    2 | NULL       |
|    3 | 2014-07-01 |
+------+------------+
3 rows in set (0.00 sec)


  
mysql> SELECT id, IFNULL(test_dt, '2014-12-31') FROM test1;
+------+-------------------------------+
| id   | IFNULL(test_dt, '2014-12-31') |
+------+-------------------------------+
|    1 | 2014-06-17                    |
|    2 | 2014-12-31                    |
|    3 | 2014-07-01                    |
+------+-------------------------------+
3 rows in set (0.00 sec)

本回答被提问者和网友采纳

MySQL 性能优化:按日期时间字段排序

【中文标题】MySQL 性能优化:按日期时间字段排序【英文标题】:MySQL performance optimization: order by datetime field 【发布时间】:2010-10-17 10:17:33 【问题描述】:

我有一个包含大约 100.000 个博客帖子的表格,通过 1:n 关系链接到一个包含 50 个提要的表格。当我使用 select 语句查询两个表时,按张贴表的日期时间字段排序,MySQL 总是使用文件排序,导致查询时间非常慢(> 1 秒)。这是postings 表的架构(简化):

+---------------------+--------------+------+-----+---------+----------------+
| Field               | Type         | Null | Key | Default | Extra          |
+---------------------+--------------+------+-----+---------+----------------+
| id                  | int(11)      | NO   | PRI | NULL    | auto_increment |
| feed_id             | int(11)      | NO   | MUL | NULL    |                |
| crawl_date          | datetime     | NO   |     | NULL    |                |
| is_active           | tinyint(1)   | NO   | MUL | 0       |                |
| link                | varchar(255) | NO   | MUL | NULL    |                |
| author              | varchar(255) | NO   |     | NULL    |                |
| title               | varchar(255) | NO   |     | NULL    |                |
| excerpt             | text         | NO   |     | NULL    |                |
| long_excerpt        | text         | NO   |     | NULL    |                |
| user_offtopic_count | int(11)      | NO   | MUL | 0       |                |
+---------------------+--------------+------+-----+---------+----------------+

这是feed 表:

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| type        | int(11)      | NO   | MUL | 0       |                |
| title       | varchar(255) | NO   |     | NULL    |                |
| website     | varchar(255) | NO   |     | NULL    |                |
| url         | varchar(255) | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+

这是执行时间超过 1 秒的查询。请注意,post_date 字段有一个索引,但 MySQL 没有使用它来对发帖表进行排序:

SELECT 
    `postings`.`id`, 
    UNIX_TIMESTAMP(postings.post_date) as post_date, 
    `postings`.`link`, 
    `postings`.`title`, 
    `postings`.`author`, 
    `postings`.`excerpt`, 
    `postings`.`long_excerpt`, 
    `feeds`.`title` AS feed_title, 
    `feeds`.`website` AS feed_website
FROM 
    (`postings`)
JOIN 
    `feeds` 
ON 
    `feeds`.`id` = `postings`.`feed_id`
WHERE 
    `feeds`.`type` = 1 AND 
    `postings`.`user_offtopic_count` < 10 AND 
    `postings`.`is_active` = 1
ORDER BY 
    `postings`.`post_date` desc
LIMIT 
    15  

explain extended 命令对该查询的结果表明 MySQL 正在使用文件排序:

+----+-------------+----------+--------+---------------------------------------+-----------+---------+--------------------------+-------+-----------------------------+
| id | select_type | table    | type   | possible_keys                         | key       | key_len | ref                      | rows  | Extra                       |
+----+-------------+----------+--------+---------------------------------------+-----------+---------+--------------------------+-------+-----------------------------+
|  1 | SIMPLE      | postings | ref    | feed_id,is_active,user_offtopic_count | is_active | 1       | const                    | 30996 | Using where; Using filesort |
|  1 | SIMPLE      | feeds    | eq_ref | PRIMARY,type                          | PRIMARY   | 4       | feedian.postings.feed_id |     1 | Using where                 |
+----+-------------+----------+--------+---------------------------------------+-----------+---------+--------------------------+-------+-----------------------------+

当我删除order by 部分时,MySQL 停止使用文件排序。如果您对如何优化此查询以使 MySQL 使用索引对数据进行排序和选择有任何想法,请告诉我。正如一些博客文章所建议的那样,我已经尝试了一些事情,例如在所有 where/order by 字段上创建组合索引,但这也不起作用。

【问题讨论】:

我真的很喜欢你提出这个问题的清晰而详细的方式。 【参考方案1】:

postings (is_active, post_date)(按此顺序)上创建一个复合索引。

它将用于过滤is_active 和按post_date 排序。

MySQL 应该在EXPLAIN EXTENDED 中的该索引上显示REF 访问方法。

请注意,您在user_offtopic_count 上有一个RANGE 过滤条件,这就是为什么您不能在过滤和按其他字段排序时对该字段使用索引的原因。

根据您的user_offtopic_count 的选择性(即满足user_offtopic_count &lt; 10 的行数),在user_offtopic_count 上创建索引并让post_dates 排序可能更有用。

为此,请在postings (is_active, user_offtopic_count) 上创建一个复合索引,并确保在该索引上使用RANGE 访问方法。

哪个索引会更快取决于您的数据分布。创建两个索引,FORCE 他们看看哪个更快:

CREATE INDEX ix_active_offtopic ON postings (is_active, user_offtopic_count);
CREATE INDEX ix_active_date ON postings (is_active, post_date);

SELECT 
    `postings`.`id`, 
    UNIX_TIMESTAMP(postings.post_date) as post_date, 
    `postings`.`link`, 
    `postings`.`title`, 
    `postings`.`author`, 
    `postings`.`excerpt`, 
    `postings`.`long_excerpt`, 
    `feeds`.`title` AS feed_title, 
    `feeds`.`website` AS feed_website
FROM 
    `postings` FORCE INDEX (ix_active_offtopic)
JOIN 
    `feeds` 
ON 
    `feeds`.`id` = `postings`.`feed_id`
WHERE 
    `feeds`.`type` = 1 AND 
    `postings`.`user_offtopic_count` < 10 AND 
    `postings`.`is_active` = 1
ORDER BY 
    `postings`.`post_date` desc
LIMIT 
    15

/* This should show RANGE access with few rows and keep the FILESORT */

SELECT 
    `postings`.`id`, 
    UNIX_TIMESTAMP(postings.post_date) as post_date, 
    `postings`.`link`, 
    `postings`.`title`, 
    `postings`.`author`, 
    `postings`.`excerpt`, 
    `postings`.`long_excerpt`, 
    `feeds`.`title` AS feed_title, 
    `feeds`.`website` AS feed_website
FROM 
    `postings` FORCE INDEX (ix_active_date)
JOIN 
    `feeds` 
ON 
    `feeds`.`id` = `postings`.`feed_id`
WHERE 
    `feeds`.`type` = 1 AND 
    `postings`.`user_offtopic_count` < 10 AND 
    `postings`.`is_active` = 1
ORDER BY 
    `postings`.`post_date` desc
LIMIT 
    15

/* This should show REF access with lots of rows and no FILESORT */

【讨论】:

这对我有用,非常感谢!我不得不使用强制索引来获得使用的最佳索引。我们现在为不同的查询使用多个组合索引。 像一个魅力一样工作,强制索引确实在它所在的位置,当添加子查询时,优化器似乎把事情扔掉了。【参考方案2】:

MySQL 有两种文件排序算法:一种用于对磁盘上的记录进行排序的旧文件排序,另一种在内存中工作的新版本。

如果它不能使用连接中第一个表上的索引对查询进行排序,则必须进行文件排序。如果排序前转换为固定宽度格式的结果集大于排序缓冲区 OR 如果它包含任何文本字段,则必须使用较慢的磁盘文件排序算法(第二个条件满足您的查询有一个文本字段)。

MySQL 选择使用 is_active 列,表面上是因为它认为该列在继续使用其他连接和 where 条件之前在消除行方面最具选择性。我建议的第一件事是尝试使用 post_date、feed_id 和 where 条件中的列创建复合索引,例如(is_active、user_offtopic_count、post_date、feed_id)。

【讨论】:

【参考方案3】:

此外,重要的是要记住,如果您排序的列具有应用于它的函数,MySQL 将不会使用索引。

您还应该尝试将 posts.post_date 别名为其他名称。这将告诉 MySQL 按未更改的列排序,您仍将选择 unix 时间戳。

【讨论】:

以上是关于mysql 日期排序查询,就是有张表,但是表的时间不全,但是我想没有数据的日期也查出来,怎么搞?的主要内容,如果未能解决你的问题,请参考以下文章

SQLSERVER有张表,需要每晚自动实现行转列。

sql查询:使用内连接查询两张表的时候,如果左边表的一条记录对应了右边表的两条记录,结果显示排列问题

MySQL 现在有张表Temp,如图,想把字段中逗号全部给去掉,请问该怎么处理?谢谢

MySQL 性能优化:按日期时间字段排序

数据库有张表,里面有字段:姓名、语文、数学、英语,怎么显示每个学生的平均成绩

ORACLE分组排序查询