简体   繁体   中英

mysql join on same table and column names

I have a table profile_data , structured like this:

id, user_id, field_id, value

I need to get user_id for any users that have a match one of several zipcodes and their country is United States.

So far I have this non-working query:

SELECT data1.user_id 
  FROM profile_data data1, profile_data data2 
 WHERE data1.field_id = 80
   AND ( value = '94114' OR value = '94146' OR value = '94117' )
   AND data2.field_id = 90
   AND value = 'United States'

Try this

SELECT DISTINCT user_id 
FROM profile_data data1
WHERE field_id = 80 AND value IN ('94114', '94146', '94117')
    AND EXISTS   (SELECT * 
              FROM profile_data 
              WHERE field_id = 90 
                  AND value = 'United States' 
                  AND user_id = data1.user_id)

Assuming you have a profile and profile data table, you could do this and avoid the distinct sort:

SELECT user_id 
FROM profile
WHERE EXISTS (SELECT * 
              FROM profile_data 
              WHERE field_id = 80 
                  AND value IN ('94114','94146','94117') 
                  AND user_id = profile.user_id)
AND EXISTS   (SELECT * 
              FROM profile_data 
              WHERE field_id = 90 
                  AND value = 'United States' 
                  AND user_id = profile.user_id)

EDIT I removed one of my subqueries per Kris' solution/refinement.

Here's my take on what you might be trying to do:

SELECT user_id
FROM profile_data
WHERE (field_id = 80 AND value IN ('94114', '94146', '94117'))
OR (field_id = 90 AND value = 'United States')

EDIT

I'm sorry, I didn't realize that there might be multiple rows per user. If that is the case then the above won't work. The edited exists statement in the answer above will. although you don't need to do both as subqueries:

 SELECT user_id FROM profile_data p1
 WHERE (field_id = 80 AND value IN ('94114', '94146', '94117'))
 AND EXISTS (SELECT 1 FROM profile_data p2 WHERE field_id = 90 AND value = 'United States' AND p1.user_id = p2.user_id)

Hopefully your optimizer will reduce it to the correct number of joins anyway.

As an aside, zip codes are country-specific. So this specific example is redundant, but there are plenty of valid use-cases.

Try this:

SELECT us_users.user_id
FROM
    (
        SELECT user_id
        FROM profile_data
        WHERE field_id = 90 AND value = 'United States'
    ) AS us_users
    INNER JOIN (
        SELECT user_id
        FROM profile_data
        WHERE field_id = 80 AND value IN ('94114','94146','94117')
    ) AS zipcodes
        ON us_users.user_id = zipcodes.user_id

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM