Mysql 如何从联合查询返回数据
我有3个表:视频、视频类别和视频类别 一个视频可以有多个视频类别,一个视频类别可以在多个视频中关联:因此,视频类别连接表 表:视频 表:视频类别 表:视频\类别\加入 给定一个video_id,我想返回20个与video_id具有相同类别的视频 如果结果集返回的视频少于20个,我希望能够通过随机挑选视频进行补偿,直到我得到20个视频。优先级始终是挑选具有相同类别的视频,如果需要,随机挑选视频,直到我得到20个视频 因此,如果video_id=24,结果集将返回Mysql 如何从联合查询返回数据,mysql,Mysql,我有3个表:视频、视频类别和视频类别 一个视频可以有多个视频类别,一个视频类别可以在多个视频中关联:因此,视频类别连接表 表:视频 表:视频类别 表:视频\类别\加入 给定一个video_id,我想返回20个与video_id具有相同类别的视频 如果结果集返回的视频少于20个,我希望能够通过随机挑选视频进行补偿,直到我得到20个视频。优先级始终是挑选具有相同类别的视频,如果需要,随机挑选视频,直到我得到20个视频 因此,如果video_id=24,结果集将返回 | video_id | |---
| video_id |
|----------|
| 78 |
| 91 |
| 12 |
| 88 |
| 34 |
视频id 74和91与视频id 24具有相同的类别,因此始终位于顶部。然后,要获得多达20个视频,结果集将返回随机视频id 12、34和91
我问了很多问题,发现我需要一个联合类型的查询。这是我从这里提出的问题中得出的结论。。。我快到了,我只需要完成最后一个查询就可以得到视频id 12、88和34
SELECT video_id, title, duration
FROM (
(
SELECT v.video_id, v.title, v.duration, 1 AS preferred
FROM video_category_join vc
JOIN video_category_join vc2 ON vc2.video_category_id = vc.video_category_id AND vc2.video_id <> vc.video_id
JOIN video v ON v.video_id = vc2.video_id
WHERE vc.video_id = 24
GROUP BY vc2.video_id
ORDER BY RAND()
LIMIT 20
)
UNION
(
...
)
) AS t1
ORDER BY preferred
LIMIT 20
您需要在与您搜索的视频具有相同类别的所有视频与表中的所有行之间进行合并。
联合结果集的行将因首选列的值而异。
然后分组,只保留普通视频的最小首选项,最后按首选项和随机数排序:
您的MySql版本是什么?@forpas MySql版本是5.6.41-84.1这非常适合。但第一行是否需要重复?也许有什么我看不到的。我创建了一个通过删除第一行就可以正常工作的示例:我已经使用了您的解决方案,nad提出了这个较短的版本。你觉得有什么问题吗?谢谢@Marco我找不到你的解决方案有任何问题,当然你必须用你的数据进行测试。但我认为您希望从第二个查询中获得随机行,这就是为什么我在解决方案中选择外部选择。每次为相同的搜索视频运行代码时,代码将返回相同的行。如果这符合您的要求,那么可以。
| video_id | video_category_id |
|------------------------------|
| 24 | 4 |
| 24 | 5 |
| 78 | 4 |
| 78 | 5 |
| 88 | 1 |
| 91 | 4 |
| 91 | 1 |
| video_id |
|----------|
| 78 |
| 91 |
| 12 |
| 88 |
| 34 |
SELECT video_id, title, duration
FROM (
(
SELECT v.video_id, v.title, v.duration, 1 AS preferred
FROM video_category_join vc
JOIN video_category_join vc2 ON vc2.video_category_id = vc.video_category_id AND vc2.video_id <> vc.video_id
JOIN video v ON v.video_id = vc2.video_id
WHERE vc.video_id = 24
GROUP BY vc2.video_id
ORDER BY RAND()
LIMIT 20
)
UNION
(
...
)
) AS t1
ORDER BY preferred
LIMIT 20
select t.video_id, t.title, t.duration
from (
select
t.video_id, t.title, t.duration, min(t.preferred) preferred
from (
select distinct v.*, 1 preferred
from video v inner join video_category_join j
on j.video_id = v.video_id
where v.video_id <> 24
and j.video_category_id in (
select video_category_id
from video_category_join
where video_id = 24
)
union all
select video_id, title, duration, 2 preferred
from video
where video_id <> 24
) t
group by t.video_id, t.title, t.duration
) t
order by preferred, rand()
limit 20
| video_id | title | duration |
| -------- | ------- | -------- |
| 91 | title91 | 190 |
| 78 | title78 | 190 |
| 34 | title34 | 190 |
| 12 | title12 | 190 |