UNION查询功能和查询结构

时间:2018-11-10 12:04:48

标签: mysql sql not-exists

我要实现的目标是,如果该值在2个额外的表中不存在,则将值插入到表中。

INSERT INTO visitor(
  visitor_username,
  email,
  PASSWORD
)
SELECT * FROM
(
SELECT
    'admin2000',
    'adminemail@mail.com',
    '123456'
) AS tmp
WHERE NOT EXISTS
(
SELECT
    admin.admin_username,
    admin.email
FROM
    admin AS admin
WHERE
    admin.admin_username = 'admin2000' AND admin.email = 
'adminemail@mail.com'
UNION
SELECT
staff.staff_username,
staff.email
FROM
staff AS staff
WHERE
staff.staff_username = 'admin2000' AND staff.email = 
'adminemail@mail.com'
 )
LIMIT 1

在WHERE NOT EXIST部分中,当我只要求输入* _username(例如:admin_username或staff_username)时,它运行良好,但是当我需要验证电子邮件是否也存在时,它就无法正常工作。

我使用WHERE NOT EXIST是否正确?如果表“ admin”上存在用户名“ admin2000”和电子邮件“ adminemail@mail.com”,而我正尝试将其插入“ visitor”表中,则会将其插入,并且不应该这样做。

2 个答案:

答案 0 :(得分:1)

问题是子查询中的AND。它搜索具有该用户名和该电子邮件的行。因此,如果您有一个名为admin2000的管理员,但使用不同的电子邮件地址,则该子查询不会返回该管理员,因此将插入新行。

使用OR代替AND,问题将得到解决。

答案 1 :(得分:0)

您似乎想编写这样的查询:

INSERT INTO visitor (visitor_username, email, PASSWORD)
    SELECT t.*
    FROM (SELECT 'admin2000' as visitor_username, 'adminemail@mail.com' as email, '123456' as PASSWORD
         ) t
    WHERE NOT EXISTS (SELECT 1
                      FROM admin a
                      WHERE a.visitor_username = t.visitor_username AND a.email = t.email
                     )
    UNION 
    SELECT s.staff_username, s.email, ? as password
    FROM staff s
    WHERE s.staff_username = 'admin2000' AND s.email = 
'adminemail@mail.com';

请注意,第二个子查询缺少密码,因此出现错误。

这看起来更简洁,只需使用一个查询即可:

INSERT INTO visitor (visitor_username, email, PASSWORD)
    SELECT t.*
    FROM (SELECT 'admin2000' as visitor_username, 'adminemail@mail.com' as email, '123456' as PASSWORD
         ) t
    WHERE NOT EXISTS (SELECT 1
                      FROM admin a
                      WHERE a.admin_username = t.visitor_username AND a.email = t.email
                     ) AND
          NOT EXISTS (SELECT 1
                      FROM staff s
                      WHERE s.staff_username = t.visitor_username AND s.email = t.email
                     );