0

我在 MySQL 数据库中有以下表格:

+------------------------+
|          Users         |
+----+--------+----------+
| id | name   | role     |
+----+--------+----------+
| 1  | Martin | admin    |
+----+--------+----------+
| 2  | George | admin    |
+----+--------+----------+
| 3  | John   | employee |
+----+--------+----------+

+-------------------------+
|          Forms          |
+----+--------------------+
| id | type               |
+----+--------------------+
| 10 | marketing_form     |
+----+--------------------+
| 11 | client_survey_form |
+----+--------------------+
| 12 | client_survey_form |
+----+--------------------+

+---------------------------------------------+
|              UsersAssignToForms             |
+----+---------+---------+--------------------+
| id | user_id | form_id | additional_comment |
+----+---------+---------+--------------------+
| 20 | 1       | 10      | Lorem ipsum...     |
+----+---------+---------+--------------------+
| 21 | 2       | 10      | Lorem ipsum....    |
+----+---------+---------+--------------------+
| 22 | 3       | 10      | null               |
+----+---------+---------+--------------------+
| 23 | 3       | 11      | null               |
+----+---------+---------+--------------------+

我想要结果:

+---------+---------+------------+--------------------+--------------------+
| user_id | form_id | first_name | form_type          | additional_comment |
+---------+---------+------------+--------------------+--------------------+
| 1       | 10      | Martin     | marketing_form     | Lorem ipsum...     |
+---------+---------+------------+--------------------+--------------------+
| 3       | 11      | John       | client_survey_form | null               |
+---------+---------+------------+--------------------+--------------------+
| null    | 12      | null       | client_survey_form | null               |
+---------+---------+------------+--------------------+--------------------+

首先,我想限制从联接查询返回的用户数量(每个表单一个用户)。如果将具有admin角色的用户分配给表单,我想显示此用户(将admin角色优先于employee角色)并将返回的用户数限制为 1,如果admin未分配,但employee已分配查询应返回此用户,如果没有分配查询应该返回空值(可能是左连接或右连接)。

我在 stackoverflow 上看到了这个问题 - MySQL JOIN with LIMIT 1 onjoined table,但不幸的是,第一个答案有 n+1 个问题,其余答案是通过简单的一次连接完成的。出于我的目的,我需要加入更多表格,但不想在上面设计这些表格来阐明我想要实现的目标,但这非常重要。

所以我的查询可能看起来像:

SELECT u.id, f.id, u.name, f.type, uf.additional_comment, [more selects from other tables...] FROM Forms as f
LEFT JOIN Users as u ON ......
INNER JOIN UsersAssignToForms as uf ON .....
[here i would like to put more and more inner joins.....]
4

1 回答 1

2

在 MySql >= 8.0 中,您可以使用某些条件对行进行编号(每个条件Form从 1 和 开始order by u.role ASC and u.id ASC),然后您可以过滤具有第一名的行:

WITH sq AS (SELECT u.id AS user_id, f.id AS form_id, u.name, f.type, uf.additional_comment,
                   ROW_NUMBER() OVER (PARTITION BY f.id ORDER BY u.role ASC, u.id ASC) AS num
       
            FROM Forms AS f
            LEFT JOIN UsersAssignToForms AS uf ON f.id = uf.form_id
            LEFT JOIN Users AS u ON u.id = uf.user_id)
            
SELECT *
FROM sq
WHERE num = 1;

在 MySql 8.0 之前,您可以尝试这样的事情(想法相同,但实现不同):

SELECT sq2.user_id, sq2.form_id, sq2.name, sq2.type, sq2.additional_comment
FROM (
    SELECT 
           sq1.*,
           
           @row_number:=CASE WHEN @form_id = sq1.form_id THEN @row_number + 1 ELSE 1 END AS num,
           @form_id:= sq1.form_id
        
    FROM (SELECT u.id AS user_id, f.id AS form_id, u.name, f.type, uf.additional_comment
          FROM Forms AS f
          LEFT JOIN UsersAssignToForms AS uf ON f.id = uf.form_id
          LEFT JOIN Users AS u ON u.id = uf.user_id
          ORDER BY f.id ASC, u.role ASC, u.id ASC) AS sq1
          
    ORDER BY sq1.form_id) AS sq2

WHERE sq2.num = 1;
于 2021-09-18T10:58:03.177 回答