根据参数集

时间:2015-05-09 05:24:57

标签: mysql

我正在尝试获得一个独特的结果列表,根据用户而不同,所选结果将基于一组参数。为了分解它,我有用户,日志和文件。每个用户可以使用多个日志,并且可以拥有多个文件。文件可以与日志关联,也可以不与日志关联,也可以将“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

非常感谢任何帮助。

1 个答案:

答案 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,我们可以选择所需的记录,即每个“用户”分区中具有最高优先级的记录。

SQL Fiddle Demo