【问题标题】:Selecting across multiple tables with UNION使用 UNION 跨多个表进行选择
【发布时间】:2011-08-29 07:13:33
【问题描述】:

我将我的数据库从一个用户表重新设计为多个用户表(按角色划分):tblStudentstblTeacherstblAdmin

登录时,我不想运行三个查询来检查用户是否存在于我的数据库中。所以我所做的就是将以下查询与union

select s.id as id, s.email as email, s.password as password, s.role as role from tblStudents s
union
select a.id as id, a.email as email, a.password as password, a.role as role from tblAdmin a
union
select t.id as id, t.email as email, t.password as password, t.role as role from tblTeachers t

这会选择所有表中相同的字段并为我很好地输出结果。

所以,我决定尝试一下,但由于某种原因,我的登录表单不起作用。对于我的登录表单,我添加了一个where 子句来检查电子邮件地址。我在我的数据库应用程序中运行了查询,令人惊讶的是,当我这样做时,例如 where email = "admin@admin.be"(此电子邮件存在于我的数据库中 tblAdmin),它还会从我的学生表中选择一条记录。

带有where子句:

select s.id as id, s.email as email, s.password as password, s.role as role from tblStudents s
union
select a.id as id, a.email as email, a.password as password, a.role as role from tblAdmin a
union
select t.id as id, t.email as email, t.password as password, t.role as role from tblTeachers t
where email = "admin@admin.be"

记录都是have id = 1,但我不明白为什么在我过滤管理员电子邮件地址时它会选择学生记录。为什么是这样?有人可以解释并为我提供更好的解决方案吗?我基本上只有一个登录表单,需要在多个表中进行选择以检查用户是否存在于我的数据库中。

【问题讨论】:

  • 这似乎不是您的完整查询,因为其中没有过滤。你能发布整个查询吗?
  • 认为这很清楚;用其他查询更新:)
  • 我注意到您没有将字符串放在引号中。是不是打错字了?
  • 如果您的意思是电子邮件 = 一个,是的,我忘记了;已编辑。
  • 关于相关话题;尽量避免使用 "" 来引用你的字符串。不幸的是,MySQL 确实允许这样做,但是如果您必须迁移到另一个数据库,它会向您吐口水。使用 '' 是 SQL 标准,适用于 MySQL 其他所有内容。

标签: mysql select union


【解决方案1】:

感谢您更新查询;现在我们可以看到 WHERE 条件仅适用于 last UNIONed 查询。您需要或者将该 WHERE 子句添加到每个查询中,或者将其包装为子选择并将 WHERE 子句应用于该查询。

select s.id as id, s.email as email, s.password as password, s.role as role from tblStudents s
where email = "admin@admin.be"
union
select a.id as id, a.email as email, a.password as password, a.role as role from tblAdmin a
where email = "admin@admin.be"
union
select t.id as id, t.email as email, t.password as password, t.role as role from tblTeachers t
where email = "admin@admin.be"

SELECT * FROM (
select s.id as id, s.email as email, s.password as password, s.role as role from tblStudents s
union
select a.id as id, a.email as email, a.password as password, a.role as role from tblAdmin a
union
select t.id as id, t.email as email, t.password as password, t.role as role from tblTeachers t
) foo where email = "admin@admin.be"

【讨论】:

  • 非常感谢。我去试试:D
  • 对于第二个示例,我收到以下错误:'每个派生表都必须有自己的别名'。
  • 那个“foo”到底是做什么的?和我用tblAdmin a做的一样吗?感谢您的宝贵时间!
  • 是子选择的别名;它只是给它一个您可以引用的名称,例如当您执行“选择 s.id 作为 id”时。这将允许您通过说select foo.email FROM (...) foo 从子选择中仅选择某些字段。如果它更清楚,您可以(在大多数 RDBMS 中)说“AS foo”而不仅仅是“foo”。名称本身是任意的;随便你怎么称呼它,我只是默认使用 foo :)
  • 好的,现在说得通了。为了清楚起见,我将其称为“用户”。非常感谢!
【解决方案2】:
SELECT
    R.co_C,
    company3.Statuss
FROM
    (
        SELECT
            company1.co_C
        FROM
            company1
        UNION ALL
            SELECT
                company2.co_C
            FROM
                company2
    ) AS R
LEFT JOIN company3 ON R.co_C = company3.co_A;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多