我看过关于此类事情的类似帖子,但我需要个人帮助来解决我的问题。
我们拥有的是一个媒体站点,当选择一个媒体项时,它会在边栏中显示三个相关的媒体项。这些项目应该显示两个项目的日期晚于当前选择的日期,一个日期早于当前选择的项目。如果没有两个日期较晚,则只显示一个日期较晚的和两个日期较早的。如果当前选择的媒体已经是最新的(没有更晚的相关媒体),则只显示三个更早的媒体。当然,这三个结果需要是与当前所选媒体日期最接近的三个。
我有一个几乎完美运行的查询:
$query = "
(SELECT
media.*,
media_series.series_name,
media_books.book_name,
media_books.book_shortname
FROM media
LEFT JOIN media_series ON media.series = media_series.id
LEFT JOIN media_books ON media.book = media_books.id
WHERE media.date >= '$media_date' AND media.series = '$series_id'
AND media.id <> '$media_id_2'
ORDER BY ABS(DATEDIFF(media.date, '$media_date')) LIMIT 2)
UNION
(SELECT
media.*,
media_series.series_name,
media_books.book_name,
media_books.book_shortname
FROM media
LEFT JOIN media_series ON media.series = media_series.id
LEFT JOIN media_books ON media.book = media_books.id
WHERE media.date <= '$media_date' AND media.series = '$series_id'
AND media.id <> '$media_id_2'
ORDER BY ABS(DATEDIFF(media.date, '$media_date')))
ORDER BY date DESC LIMIT 3
";
第一个 SELECT
获取最多两个具有较晚日期的项目,然后使用 UNION
,第二个 SELECT
获取任何具有更早的日期。最后,最后的 LIMIT 3
确保我们总共只得到三行。
我能看到的这个查询的唯一缺陷是,如果当前选择的媒体是最旧的(意味着它没有更早日期的相关媒体),那么只会显示两个结果,因为第一个 SELECT
限制为 2,第二个 SELECT
不返回任何内容。
只有当第二个 SELECT
返回零行时,我才需要第一个 SELECT
返回 3 行。我在想我可以以某种方式使用 CASE
,但我不确定具体如何。你能帮忙吗?
注意:作为临时解决方案,我目前正在运行查询,然后使用 PHP 检查返回的行数,如果小于 3,我将再次运行整个查询,但使用 LIMIT 3
在第一个 SELECT
中。这可行,但我想尽可能避免运行这两个查询。
谢谢。
最佳答案
尝试:
$query = "
SELECT * FROM
(SELECT * FROM
(SELECT
media.*,
media_series.series_name,
media_books.book_name,
media_books.book_shortname,
@rn := @rn + 2 rn
FROM (SELECT @rn :=-1 ) r
CROSS JOIN media
LEFT JOIN media_series ON media.series = media_series.id
LEFT JOIN media_books ON media.book = media_books.id
WHERE media.date >= '$media_date' AND media.series = '$series_id'
AND media.id <> '$media_id_2'
ORDER BY media.date LIMIT 3) sq1
UNION ALL
(SELECT
media.*,
media_series.series_name,
media_books.book_name,
media_books.book_shortname,
@rn := @rn + 2 rn
FROM (SELECT @rn :=0 ) r
CROSS JOIN media
LEFT JOIN media_series ON media.series = media_series.id
LEFT JOIN media_books ON media.book = media_books.id
WHERE media.date < '$media_date' AND media.series = '$series_id'
AND media.id <> '$media_id_2'
ORDER BY media.date DESC LIMIT 3) sq2
ORDER BY rn LIMIT 3) mq
ORDER BY date DESC
";
(第一个 SELECT * FROM
可能不是必需的 - 如果直接通过 SQL 运行此查询,则可能是必需的,但代码中的等效行不存在,因此它可能会在其他地方自动生成.)
概念证明 here .
关于MySQL - 我怎样才能使我的查询条件基于它会返回的行数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15577662/