我正在尝试获得一个独特的结果列表,根据用户而不同,所选结果将基于一组参数。为了分解它,我有用户,日志和文件。每个用户可以使用多个日志,并且可以拥有多个文件。文件可以与日志关联,也可以不与日志关联,也可以将“billing”标志设置为true。当有人选择日志时我想要做的就是调出与“billing”标志和日志最密切相关的文件列表。
如果用户有一个与日志关联的文件并且具有 'billing'标志设置为true,即该用户的结果。
如果不可用,则下一个是仅将“billing”标志设置为true的文件(与任何最高日志关联或无关联)。
如果没有,则为最高日志编号。
以下是表格的概括:
测试表:
+----+------+-----+
| ID | user | log |
+----+------+-----+
| 1 | 1 | 2 |
| 2 | 1 | 2 |
| 3 | 2 | 2 |
| 4 | 3 | 2 |
| 5 | 3 | 2 |
| 6 | 4 | 2 |
+----+------+-----+
文件表:
+----+-------+-----+---------+------+
| ID | file | log | billing | user |
+----+-------+-----+---------+------+
| 1 | a.pdf | 2 | 0 | 1 |
| 2 | b.pdf | 3 | 1 | 1 |
| 3 | c.pdf | 1 | 0 | 2 |
| 4 | d.pdf | 2 | 1 | 2 |
| 5 | e.pdf | 1 | 0 | 3 |
| 6 | f.pdf | 3 | 0 | 3 |
| 7 | g.pdf | 0 | 1 | 4 |
| 8 | h.pdf | 1 | 0 | 4 |
| 9 | i.pdf | 2 | 1 | 4 |
| 10 | j.pdf | 3 | 0 | 4 |
+----+-------+-----+---------+------+
在这种情况下,我想得到:
+------+-------+-----+---------+
| user | file | log | billing |
+------+-------+-----+---------+
| 1 | b.pdf | 3 | 1 |
| 2 | d.pdf | 2 | 1 |
| 3 | f.pdf | 3 | 0 |
| 4 | i.pdf | 2 | 1 |
+------+-------+-----+---------+
到目前为止,我的简化查询会返回用户的所有文件,但我在根据上述参数进行分组时遇到问题。
SELECT
user,
file,
log,
billing
FROM
files
WHERE
user IN (
SELECT
DISTINCT(user)
FROM
tests
WHERE
log = 2
)
ORDER BY
CASE
WHEN log = 2 AND billing = 1 THEN 1
WHEN billing = 1 THEN 2
ELSE -1
END
非常感谢任何帮助。
答案 0 :(得分:1)
您可以使用单独的查询来根据OP中指定的3个条件中的每个条件获取结果,然后UNION
来自这些查询的结果,并从第一个查询中获取结果(如果可用),否则从第二个查询中获取,否则来自第三个查询:
SELECT user, file, log, billing
FROM (
SELECT @row_number:=CASE WHEN @user=user THEN @row_number+1
ELSE 1
END AS row_number,
@user:=user AS user,
file, log, billing
FROM (
-- 1st query: has biggest priority
SELECT 1 AS pri, t.user, f.file, f.log, f.billing
FROM (SELECT DISTINCT user, log
FROM tests
WHERE log = 2) AS t
INNER JOIN files AS f
ON (t.user = f.user AND t.log = f.log AND f.billing = 1)
UNION ALL
-- 2nd query: priority = 2
SELECT 2 AS pri, t.user, f.file, f.log, f.billing
FROM (SELECT DISTINCT user, log
FROM tests
WHERE log = 2) AS t
INNER JOIN files AS f
ON (t.user = f.user AND f.billing = 1)
WHERE f.log > t.log OR f.log = 0
UNION ALL
-- 3rd query: priority = 3
SELECT 3 AS pri, t.user, f.file, f.log, f.billing
FROM (SELECT DISTINCT user, log
FROM tests
WHERE log = 2) AS t
INNER JOIN files AS f ON (t.user = f.user)
ORDER BY user, pri, log DESC ) s ) r
WHERE r.row_number = 1
ORDER BY user
pri
列用于识别三个单独查询之间的结果并确定其优先级。 @row_number
和@user
变量用于模拟ROW_NUMBER() OVER (PARTITION BY user ORDER BY pri)
窗口函数。在最外层的查询中使用@row_number
,我们可以选择所需的记录,即每个“用户”分区中具有最高优先级的记录。