MySQL return 列如果用户名属于禁用组

MySQL return column if username part of disabled group

我有两个table如下

radcheck

+----+-------------------+--------------------+----+--------+
| id | username          | attribute          | op | value  |
+----+-------------------+--------------------+----+--------+
|  1 | userA             | Cleartext-Password | := | Apass  |
|  2 | userB             | Cleartext-Password | := | Bpass  |
|  3 | DC:9F:DB:xx:xx:xx | Auth-Type          | := | Accept |
|  4 | userC             | Cleartext-Password | := | Cpass  |
+----+-------------------+--------------------+----+--------+

radusergroup

+----------+------------+----------+
| username | groupname  | priority |
+----------+------------+----------+
| userA    | daily-plan |        1 |
| userA    | disabled   |        0 |
| userB    | quota-plan |        1 |
| userC    | disabled   |        0 |
| userC    | try        |        1 |
+----------+------------+----------+

我使用下面的查询 return 结果列出了不属于禁用组的用户名,但我想 return 结果中的另一列称为禁用,如果属于禁用组和 0 如果不是:

SELECT c.id, c.username, c.value, g.groupname
FROM radcheck c LEFT JOIN
     radusergroup g
     USING (username)
WHERE attribute = 'Cleartext-Password' AND
      groupname <> 'disabled';

我尝试了多种使用以下查询使用三重左连接的方法,但它们似乎不起作用,结果中的组名列始终是在 radusergroup table:

中找到的第一个组名
SELECT c.id, c.username, c.value, g.groupname, (disabled.username IS NOT NULL) AS disabled
FROM radcheck c LEFT JOIN
     radusergroup g
     ON c.username = g.username LEFT JOIN
     radusergroup disabled
     ON disabled.username = c.username AND
        disabled.groupname = 'disabled'
WHERE (c.username = g.username) AND
      attribute = 'Cleartext-Password'
GROUP BY c.username;

以上输出:

+----+----------+-------+------------+----------+
| id | username | value | groupname  | disabled |
+----+----------+-------+------------+----------+
|  1 | userA    | Apass | daily-plan |        1 |
|  2 | userB    | Bpass | quota-plan |        0 |
|  4 | userC    | Cpass | disabled   |        1 |
+----+----------+-------+------------+----------+

最简单的解决方案是使用 EXISTS 和相关子查询扩展您的查询。

SELECT c.id,
       c.username,
       c.value,
       g.groupname,
       EXISTS (SELECT *
                      FROM radusergroup g2
                           WHERE g2.username = c.username
                                 AND g2.groupname = 'disabled') disabled
       FROM radcheck c
            LEFT JOIN radusergroup g
                      ON g.username = c.username
       WHERE c.attribute = 'Cleartext-Password'
             AND g.groupname <> 'disabled';

假定您的第一个查询没有问题。我无法从你的 post 判断它是否正常,因为它将 return 为用户所在的每个非禁用组排一行,即每个用户可能不止一行。如果这也是一个问题,您可以使用 g2.groupname <> 'disabled' 的模拟方式使用第二个 EXISTS 并删除左连接。


编辑:如果您只想要标志,如果用户处于禁用 and/or 非禁用组:

SELECT c.id,
       c.username,
       c.value,
       EXISTS (SELECT *
                      FROM radusergroup g2
                           WHERE g2.username = c.username
                                 AND g2.groupname = 'disabled') disabled,
       EXISTS (SELECT *
                      FROM radusergroup g2
                           WHERE g2.username = c.username
                                 AND g2.groupname <> 'disabled') not_disabled
       FROM radcheck c
       WHERE c.attribute = 'Cleartext-Password';

您可以在 SQL 查询中尝试 CASE STATEMENT。如下所示:

SELECT c.id, c.username, c.value, g.groupname, (CASE
    WHEN g.groupname = 'disabled' THEN 1
    ELSE 0
END) AS 'disabled' FROM radcheck c LEFT JOIN radusergroup g USING (username) WHERE attribute = 'Cleartext-Password';