MySQL多表条件过滤器

时间:2014-11-25 22:34:38

标签: mysql

我想从包含三种类型用户(类型user_idic)的用户表中检查p的有效性。< / p>

对于类型为c的用户有效,当前user.party_id必须出现在customer_partner表中,而不是提供的$PNR

对于类型为i的用户有效,当前的user.party_id最多出现在installer_partner表中,与提供的$PNR相对应。

对于类型为p的用户有效,当前user.party_id必须是提供的$PNR

如果有效,我希望返回的行是用户详细信息,如果无效,我希望没有行。我尝试了几种方法来做到这一点,但没有成功。

示例1:我在选择中使用CASE,然后在结果列中放置ve值,然后在WHERE语句中过滤掉,但这给了我Unknown column 'valid_user' in 'where clause'错误。

SELECT
    CASE users.party_type 
        WHEN 'c' 
        THEN IF(users.party_id IN (SELECT pnrcus.customer_id 
                                   FROM customer_partner AS pnrcus
                                   WHERE pnrcus.partner_id = '.$PNR.'),'v','e')
        WHEN 'i' 
        THEN IF(users.party_id IN (SELECT pnrins.installer_id 
                                   FROM installer_partner AS pnrins
                                   WHERE pnrins.partner_id = '.$PNR.'),'v','e')
        WHEN 'p'
        THEN IF(users.party_id = '.$PNR.','v','e')
        ELSE 'e'
    END AS valid_user,
    users.email_user_id, 
    users.party_id, 
    users.person_id, 
    users.first_name, 
    users.last_name 
FROM users AS users
WHERE LCASE(users.email_user_id) = LCASE('.$UID.') 
AND users.password = '.$PWD.'
AND valid_user = 'v'
AND users.account_status = 'a'

示例2:我在sql的OR部分使用WHERE语句。这会返回错误的行。

SELECT
    users.party_type 
    users.email_user_id, 
    users.party_id, 
    users.person_id, 
    users.first_name, 
    users.last_name
FROM users AS users
WHERE LCASE(users.email_user_id) = LCASE('.$UID.') 
AND users.password = '.$PWD.'
AND users.account_status = 'a'
AND (
    parties.party_type = 'c' 
    AND users.party_id IN (SELECT pnrcus.customer_id 
                           FROM sma_customer_partner AS pnrcus
                           WHERE pnrcus.partner_id = .$PNR.')
    ) OR (
    parties.party_type = 'i' 
    AND users.party_id IN (SELECT pnrins.installer_id 
                           FROM sma_installer_partner AS pnrins
                           WHERE pnrins.partner_id = .$PNR.')
    ) OR (
    parties.party_type = 'p' 
    AND users.party_id = '.$PNR.'
    )

1 个答案:

答案 0 :(得分:1)

快速解决您的问题是为您创建的结果集中的列添加HAVING子句:

SELECT
    CASE users.party_type 
        WHEN 'c' 
        THEN IF(users.party_id IN (SELECT pnrcus.customer_id 
                                   FROM customer_partner AS pnrcus
                                   WHERE pnrcus.partner_id = '.$PNR.'),'v','e')
        WHEN 'i' 
        THEN IF(users.party_id IN (SELECT pnrins.installer_id 
                                   FROM installer_partner AS pnrins
                                   WHERE pnrins.partner_id = '.$PNR.'),'v','e')
        WHEN 'p'
        THEN IF(parties.party_id = '.$PNR.','v','e')
        ELSE 'e'
    END AS valid_user,
    users.email_user_id, 
    users.party_id, 
    users.person_id, 
    users.first_name, 
    users.last_name 
FROM users AS users
WHERE LCASE(users.email_user_id) = LCASE('.$UID.') 
AND users.password = '.$PWD.'
AND users.account_status = 'a'
HAVING valid_user = 'v'

但是,坦率地说,我这样做了:

SELECT
    users.party_type 
    users.email_user_id, 
    users.party_id, 
    users.person_id, 
    users.first_name, 
    users.last_name
FROM users AS users
LEFT JOIN customer_partner AS pnrcus
   ON pnrcus.partner_id = '.$PNR.'
   AND pnrcus.customer_id = users.party_id
   AND users.party_type = 'c'
LEFT JOIN installer_partner AS pnrins
   ON pnrins.partner_id = '.$PNR.'
   AND pnrins.installer_id = users.party_id
   AND pnrins.party_type = 'i'
WHERE 
   LCASE(users.email_user_id) = LCASE('.$UID.') 
   AND users.password = '.$PWD.'
   AND users.account_status = 'a'
   AND (
      ( users.party_type  ='p' AND users,party_id = '.$PNR.' )
      OR pnrcus.partner_id IS NOT NULL
      OR pnrins.partner_id IS NOT NULL
   )
GROUP BY users.email_user_id;

请注意,这是非常慢:

LCASE(users.email_user_id) = LCASE('.$UID.')

您可能希望使用排序规则,其中&#39; A&#39; =&#39; a&#39; == true(所有_ci都是),或将其存储为小写,并提供小写。目前它不能使用索引。

相关问题