因此,我有一个相当基本的基于PHP的网站,该网站的某些数据使用MySQL。
我目前需要以一种依赖于其他表中可选字段的方式对MySQL结果行进行排序,我想知道这是否“轻松”可实现。
这是数据库的外观(排序):
主表称为“主”
| id | timestamp | starttime |
| 1 | 2010-06-10 | 2010-08-15 |
| 2 | 2011-01-15 | 2011-03-12 |
| 3 | 2011-01-27 | 0000-00-00 |
附表称为“附件”
| aid | timestamp | id |
| 1 | 2012-09-04 | 3 |
| 2 | 2017-04-01 | 3 |
版本表称为“修订”
| rid | timestamp | id |
| 1 | 2014-10-10 | 1 |
| 2 | 2018-12-25 | 2 |
Main表基本上是必需的,附件和修订对于我要提供的有序列表并不重要。
现在,我希望能够按“上次更改日期”对它进行排序,这是一个问题,因为可以通过以下方式对4个值进行排序:
OR(以上字段均不存在或为零)
我尝试在ORDER BY子句中使用GREATEST(),并且有效,但仅适用于Main.timestamp和Main.starttime-不适用于我需要考虑的其他两个值。
这是我当前的SQL命令:
SELECT Main.*, User.lastname, User.surname, User.title
FROM Main, User
WHERE User.uid = Main.uid AND Main.state != 0
ORDER BY $orderby LIMIT :limit OFFSET :offset
我的$ orderby变量是通过PHP处理的,因此已经过了清理,但基本上可以是这样的:
$orderby = "Main.timestamp DESC";
或使用GREATEST():
$orderby = "GREATEST(Main.timestamp, Main.starttime) DESC";
我面临的主要问题是,并非“主要”的每一行在“附件”或“修订”中都有对应的行,而有些行有多个。
上面的示例应排序为
2 > 3 > 1
如果排序有效。
希望大家能帮忙!
答案 0 :(得分:1)
有点棘手,但有效:https://www.db-fiddle.com/f/bUV99RzrxcHkgFyUWUMGEe/0
查询
SELECT
MAIN.id,
MAX(MAIN.updated_at) AS 'updated_at'
FROM (
SELECT
M.id,
GREATEST(
IFNULL(M.`timestamp`, '1970-01-01 00:00:00'),
IFNULL(M.starttime, '1970-01-01 00:00:00'),
IFNULL(A.`timestamp`, '1970-01-01 00:00:00'),
IFNULL(R.`timestamp`, '1970-01-01 00:00:00')
) AS 'updated_at'
FROM
main M
LEFT JOIN
attachment A ON M.id = A.id
LEFT JOIN
revision R ON M.id = R.id
) AS MAIN
GROUP BY
MAIN.id
ORDER BY
updated_at DESC
说明
我已经使用第一个查询来选择所有主要内容及其相关的附件和修订。然后,对于每个字段,我计算了一个updated_at
字段,该字段在许多字段之间取最大值(注:great无效,且值为空,因此IFNULL(date, '1970-01-01 00:00:00)
因此假定至少一个日期主时间戳,主开始时间,附件时间戳和修订时间戳之间的值不为null)。
目前,这些行未按主ID分组,因此您在数据库小提琴中看到4行。
我使用了第二个查询来包装最后一个查询,并且我使用了MAX(updated_at) AS 'updated_at'
来获取最多的分组查询(您看到名为AS MAIN
的包装查询是做GROUP BY MAIN.id
,这就是为什么我们使用MAX
而不是GREATEST
的原因,最后一个使用字段列表而不是分组字段)。
最后,我们通过查询和tada进行订购!
希望有帮助。