MYSQL复杂的顺序由两列混合结果

时间:2017-09-28 13:41:18

标签: mysql

我有这样的表products

CREATE TABLE IF NOT EXISTS `products` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `created_at` datetime DEFAULT NULL,
  `name` longtext,
  `place` tinyint(4) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

+----+---------------------+---------+-------+
| id |      created_at     |   name  | place |
+----+---------------------+---------+-------+
|  1 | 2000-01-01 17:00:00 | Ninth   |   0   |
|  2 | 2000-01-01 14:00:00 | Second  |   2   |
|  3 | 2000-01-01 19:00:00 | Sixth   |   0   |
|  4 | 2000-01-01 18:00:00 | Eighth  |   0   |
|  5 | 2000-01-01 15:00:00 | First   |   1   |
|  6 | 2000-01-01 16:00:00 | Tenth   |   0   |
|  7 | 2000-01-01 20:00:00 | Seventh |   7   |
|  8 | 2000-01-01 21:00:00 | Fifth   |   0   |
|  9 | 2000-01-01 23:00:00 | Fourth  |   4   |
| 10 | 2000-01-01 22:00:00 | Third   |   0   |
+----+---------------------+---------+-------+

我希望这样订购:

+----+---------------------+---------+-------+
| id |      created_at     |   name  | place |
+----+---------------------+---------+-------+
|  5 | 2000-01-01 15:00:00 | First   |   1   |
|  2 | 2000-01-01 14:00:00 | Second  |   2   |
|  9 | 2000-01-01 23:00:00 | Third   |   0   |
|  7 | 2000-01-01 20:00:00 | Fourth  |   4   |
| 10 | 2000-01-01 22:00:00 | Fifth   |   0   |
|  8 | 2000-01-01 21:00:00 | Sixth   |   0   |
|  3 | 2000-01-01 19:00:00 | Seventh |   7   |
|  4 | 2000-01-01 18:00:00 | Eighth  |   0   |
|  1 | 2000-01-01 17:00:00 | Ninth   |   0   |
|  6 | 2000-01-01 16:00:00 | Tenth   |   0   |
+----+---------------------+---------+-------+

place asc排序,不包含' 0',填写place desc。

排序的记录的缺失created_at

我最好的是:

select * from products order by `place` = 0,  `place` asc, created_at desc;

但这不会填补place个缺失。

SQLFiddle

3 个答案:

答案 0 :(得分:2)

使用ORDER BY CASE子句。 像这样。

<强>查询

SELECT 
 *
FROM 
 products
ORDER BY 
 CASE
  WHEN products.name = 'First'
  THEN 1

  WHEN products.name = 'Second'
  THEN 2

  WHEN products.name = 'Third'
  THEN 3  

  WHEN products.name = 'Fourth'
  THEN 4

  WHEN products.name = 'Fifth'
  THEN 5

  WHEN products.name = 'Sixth'
  THEN 6

  WHEN products.name = 'Seventh'
  THEN 7

  WHEN products.name = 'Eighth'
  THEN 8

  WHEN products.name = 'Ninth'
  THEN 9

  WHEN products.name = 'Tenth'
  THEN 10

 END

<强>结果

| id |           created_at |    name | place |
|----|----------------------|---------|-------|
|  5 | 2000-01-01T15:00:00Z |   First |     1 |
|  2 | 2000-01-01T14:00:00Z |  Second |     2 |
| 10 | 2000-01-01T22:00:00Z |   Third |     0 |
|  9 | 2000-01-01T23:00:00Z |  Fourth |     4 |
|  8 | 2000-01-01T21:00:00Z |   Fifth |     0 |
|  3 | 2000-01-01T19:00:00Z |   Sixth |     0 |
|  7 | 2000-01-01T20:00:00Z | Seventh |     7 |
|  4 | 2000-01-01T18:00:00Z |  Eighth |     0 |
|  1 | 2000-01-01T17:00:00Z |   Ninth |     0 |
|  6 | 2000-01-01T16:00:00Z |   Tenth |     0 |

demo http://sqlfiddle.com/#!9/77d49e/11

答案 1 :(得分:0)

这样可行,不确定是否是最佳解决方案,但试一试,

创建一个表格,您可以在其中指定所需的顺序,如下所示:

CREATE TABLE IF NOT EXISTS `ordering` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT, 
  `name` longtext,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `ordering` ( `id`, `name`) VALUES 
( '1', 'First' ), 
( '2', 'Second'), 
( '3', 'Third' ), 
( '4', 'Fourth' ), 
( '5', 'Fifth' ), 
( '6', 'Sixth' ), 
( '7', 'Seventh' ), 
( '8', 'Eighth' ), 
( '9', 'Ninth' ), 
( '10', 'Tenth' );

然后加入你的另一张桌子:

select p.* from products p 
left join ordering o on o.name = p.name
order by o.id asc 

此外,如果您这样做,最好更新您的产品架构并用prodcut.orderId替换您的product.name或类似的东西,但这取决于您

您可以在SQLFiddle

上看到结果

答案 2 :(得分:0)

为什么不填写丢失的place字段?像

这样的东西
update products set place=3 where name='Third';
update products set place=5 where name='Fifth';
.......