【问题标题】:PDO UNION function only processes first SELECT statementPDO UNION 函数只处理第一个 SELECT 语句
【发布时间】:2014-02-23 19:56:37
【问题描述】:

好的,所以我有三种不同类型的用户(开发人员、设计师和雇主),他们都有不同的数据库表。我已经成功开发了一个脚本,该脚本可以使用 UNION 从三个用户表中的任何一个登录用户。但是我现在在注册时引入了电子邮件验证,所以我需要测试“已确认”字段(在每个表中)是否有值“1”来处理成功登录(如果值为 0,则用户不会可以登录)。

    public function email_confirmed($email) {

        $query = $this->db->prepare("SELECT 
            COUNT(developers.id) FROM " . DB_NAME . ".developers WHERE developers.email=  ? AND developers.confirmed = ? 
            UNION SELECT COUNT(designers.id) FROM " . DB_NAME . ".designers WHERE designers.email = ? AND designers.confirmed = ? 
            UNION SELECT COUNT(employers.id) FROM " . DB_NAME . ".employers WHERE employers.email = ? AND employers.confirmed = ?
            ");
        $query->bindValue(1, $email);
        $query->bindValue(2, 1);
        $query->bindValue(3, $email);
        $query->bindValue(4, 1);
        $query->bindValue(5, $email);
        $query->bindValue(6, 1);

        try{

            $query->execute();
            $rows = $query->fetchColumn();

            if($rows == 1){
                return true;
            }else{
                return false;
            }

        } catch(PDOException $e){
            die($e->getMessage());
        }
    }

但目前(使用以下功能),只有开发人员可以登录。如果您尝试使用设计师或雇主帐户登录,则会显示以下错误。任何想法为什么会发生这种情况?

 if ($users->email_confirmed($email) === false) {
        $errors[] = 'Sorry, but you need to activate your account. Please check your emails.';
    } else // carry on logging in user

【问题讨论】:

    标签: mysql sql select pdo union


    【解决方案1】:

    这是您的查询:

    SELECT COUNT(developers.id)
    FROM " . DB_NAME . ".developers
    WHERE developers.email=  ? AND developers.confirmed = ? 
    UNION
    SELECT COUNT(designers.id)
    FROM " . DB_NAME . ".designers
    WHERE designers.email = ? AND designers.confirmed = ? 
    UNION
    SELECT COUNT(employers.id)
    FROM " . DB_NAME . ".employers
    WHERE employers.email = ? AND employers.confirmed = ?
    

    它正在获取三行,然后删除重复项,并任意排序。然后,您将从这些行之一中读取值(计数)。

    采取你正在采取的方法,我认为你想要:

    select COUNT(*)
    from ((select 1
           from " . DB_NAME . ".developers
           where developers.email=  ? AND developers.confirmed = ? 
          ) union all 
          (select 1
           from  " . DB_NAME . ".designers
           where designers.email = ? AND designers.confirmed = ? 
          ) union all
          (select 1
           from " . DB_NAME . ".employers
           where employers.email = ? AND employers.confirmed = ?
          )
         ) t
    

    【讨论】:

    • 完美!您会建议在此语句中为每个表使用 alias' 还是您认为这太过分了?
    • @jshjohnson 。 . .我通常喜欢使用别名,所以d 代表developers 等等。但是,就可读性而言,它对这个查询的影响很小。
    猜你喜欢
    • 2013-09-30
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多