【发布时间】:2021-01-15 15:26:08
【问题描述】:
假设我有一个带有项目的日历,当您单击其中一个时,我想提供一个下一个/上一个按钮。例如:
ID Time Name
123 8:30 Apple
432 9:00 1 Plumb
43 9:00 2:2 Kale
663 9:00 Apples
12 9:00 Berry
235 9:00 Carrot
62 11:00 Tomato
23 11:30 Pepper
在日历上列出这些很容易:
SELECT *
FROM fruits
WHERE date="2020-09-30"
ORDER BY
STR_TO_DATE(`time`, '%H:%i') ASC,
name ASC;
我遇到的问题是获得准确的下一个/上一个项目,并且只有当所有项目同时开始时才会出现问题,例如上午 9:00:
# Previous Button - Should get Apples, but it returns `Carrots`
SELECT
name
FROM fruits
WHERE
id != '12' #Berry
AND TIMESTAMP(date, time) <= TIMESTAMP('2020-09-30', '9:00')
ORDER BY
date DESC,
STR_TO_DATE(time, '%H:%i') DESC,
name DESC
LIMIT 1;
# Next Button - Should get Carrot, but it returns `1 Plumb`
SELECT
name
FROM fruits
WHERE
id != '12' #Berry
AND TIMESTAMP(date, time) >= TIMESTAMP('2020-09-30', '9:00')
ORDER BY
date ASC,
STR_TO_DATE(time, '%H:%i') ASC,
name ASC
LIMIT 1;
我明白为什么,但我不知道如何解决。
如果我可以过滤字母数字,比如 REGEX '^[Apa-p1-0]',但我必须做大量的 PHP 来确定它是数字还是 alpha,然后处理很快就会得到的变量令人困惑。另外,我可能需要循环更混乱的数组。
我可以使用一个变量,动态地对行进行编号,但是我还需要使用 PHP 来确定我在循环中的位置,然后找到下一个,我需要获取几十行来确保我不会错过任何一个。
要明确一点——这张表有数百万行,数据经常变化,多人可以随时更改数据,所以我需要一些快速和动态的东西。
我创建了一个包含上述所有数据和查询的 DB Fiddle,以便更轻松地提供任何帮助:
https://www.db-fiddle.com/f/a5qnbhUgcG9j9irkzawKHx/0
有什么想法吗?
更新 :: Nicks 回答的解决方案
查看他的答案以获得完整的解释。他的回答更加动态并且不需要 PHP,我想绕过子查询,所以我最终使用了一点 PHP。非常感谢,如果没有你的帮助,我永远不会在一个查询中解决这个问题!
PHP:
$timestamp = strtotime($date.' '.$time);
MySQL
# Previous
SELECT
name
FROM fruits
WHERE
(
UNIX_TIMESTAMP(TIMESTAMP(`date`, `time`)) - $timestamp < 0
OR
UNIX_TIMESTAMP(TIMESTAMP(`date`, `time`)) - $timestamp = 0
AND name < '$name'
)
ORDER BY
UNIX_TIMESTAMP(TIMESTAMP(`date`, `time`)) - $timestamp DESC,
name DESC
LIMIT 1;
# Next
SELECT
name
FROM fruits
WHERE
(
UNIX_TIMESTAMP(TIMESTAMP(`date`, `time`)) - $timestamp > 0
OR
UNIX_TIMESTAMP(TIMESTAMP(`date`, `time`)) - $timestamp = 0
AND name > '$name'
)
ORDER BY
UNIX_TIMESTAMP(TIMESTAMP(`date`, `time`)) - $timestamp ASC,
name ASC
LIMIT 1;
【问题讨论】:
-
由于您将决定订单是什么,如果您事先将其读入可迭代的东西(如堆栈或列表)中会怎样?
-
我想到了这个,问题是这张表有几百万行,经常变化,同样的数据可以显示在多个人同时使用的略有不同的集合中,所以就我知道没有可行的方法来预先确定订单,它必须是动态的。但是,如果更改原始顺序可能会解决问题,我愿意将其作为解决方案。无论哪种方式,使用我的小提琴的例子都会受到赞赏。
-
那你刷新表了吗?当你这样做时,我会创建数组。如果不是那么点击,但那是很多来回的服务器 idk。
-
每次显示项目日历时,是的,它只是获取数据。我有一些非常快速的索引设置。我不认为我可以创建一个数组,因为从技术上讲,您可以单击“September”中的第一项,然后您需要“August”中最后一项的上一个按钮,因此该数组必须是数百个项目很长,即使那样,您也可能会发现自己处于超出您考虑范围的情况。
-
为什么
Carrot应该在Berry之后?同时...