以下是我的表格:
files
+----+--------+
| id | name |
+----+--------+
| 2 | file_1 |
| 3 | file_2 |
| 5 | file_3 |
+----+--------+
files_already_viewed
+----+---------+----------+------+
| id | file_id | category | user |
+----+---------+----------+------+
| 1 | 3 | 5 | 1 |
| 2 | 2 | 1 | 1 |
| 3 | 5 | 1 | 1 |
+----+---------+----------+------+
categories_files_join
+--------+---------+
| cat_id | file_id |
+--------+---------+
| 1 | 2 |
| 1 | 5 |
| 5 | 3 |
| 1 | 3 |
+--------+---------+
file_2(ID为3)有两个与之关联的类别:cat_id 5和cat_id 1.
用户在类别5下搜索文件时已查看过一次。
但现在用户正在搜索类别1下的文件。
我需要一个不会在“1”类别下显示file_2的查询,直到首先查看类别ID为1的所有其他文件,因为用户已经查看了file_2。基本上将file_2放在列表的末尾。
到目前为止,这是我的查询:
SELECT name FROM files
WHERE files.id NOT IN (
SELECT file_id FROM files_already_viewed
WHERE user='1')
ORDER BY most_viewed DESC
LIMIT 1
我按最受欢迎的浏览文件排序。但我不希望显示已经查看过的文件,无论其类别如何,只有在该特定类别中查看了所有其他文件。
非常感谢任何帮助。谢谢!
答案 0 :(得分:0)
实际上,您的查询不会显示已显示的文件。你想要做的是在底部订购已经显示的文件。所以,基本上你必须要有数据集:首先,匹配所需标准的数据和用户尚未显示的数据,然后是符合所需条件但已显示用户的数据。
我处理集合的方法是为每个集合添加customSort
id,然后按顺序排序。现在简短的解释是第一组我通过使用左连接伪造一个MINUS操作得到它:我得到所有尚未看到的文件。然后,第二组更容易,因为它只需要获取已经看过的所有文件。因此,customSort顺序中两个集合的UNION将是您正在寻找的结果,所以现在您只需要按当前查询条件(在这种情况下类别= 1)过滤该结果。
select file_id from (
select distinct cf1.cat_id, cf1.file_id, 1 as customSort
from CategoriesFiles1 cf1
left join FilesViewed1 fv1 on (fv1.file_id = cf1.file_id)
where (fv1.file_id is null)
union
select distinct cf2.cat_id, cf2.file_id, 2 as customSort
from CategoriesFiles2 cf2
join FilesViewed2 fv2 on (fv2.file_id = cf2.file_id)
) FinalResult
where (FinalResult.cat_id = 1)
order by customSort
以下是example的链接。您可以在files_already_viewed中对每个数据插入进行注释,以查看在查看文件后结果是如何更改的。此外,将select file_id from
更改为select * from
可让您清楚地看到每行属于哪一组。
让我知道这是否有效。