Php mysql在相同的表名和列名上联接

Php mysql在相同的表名和列名上联接,php,mysql,sql,Php,Mysql,Sql,我有一个表profile\u data,结构如下: id, user_id, field_id, value 我需要为任何用户获取用户id,这些用户具有多个ZipCode中的一个匹配项,并且他们的国家是美国 到目前为止,我有一个非工作查询: SELECT data1.user_id FROM profile_data data1, profile_data data2 WHERE data1.field_id = 80 AND ( value = '94114' OR valu

我有一个表
profile\u data
,结构如下:

id, user_id, field_id, value
我需要为任何用户获取用户id,这些用户具有多个ZipCode中的一个匹配项,并且他们的国家是美国

到目前为止,我有一个非工作查询:

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'
试试这个

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)
假设您有一个概要文件和概要文件数据表,您可以这样做并避免不同的排序:

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)
编辑
我根据Kris的解决方案/优化删除了我的一个子查询。

以下是我对您可能尝试执行的操作的看法:

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

很抱歉,我没有意识到每个用户可能有多行。如果是这样的话,那么上述方法就行不通了。以上答案中编辑的exists语句将被删除。虽然不需要同时作为子查询执行这两项操作:

 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)
希望您的优化器能将其减少到正确的连接数

另外,邮政编码是特定于国家的。因此,这个特定的示例是多余的,但是有很多有效的用例。

试试这个:

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

您考虑过IN子句吗?您的查询毫无意义,这是如何连接的?你到底在寻找什么?您需要重新表述此SQL的结果为何在from语句中有两次profile_数据?剖面图数据是否以某种方式相互关联?(例如Employee-manager)由于两个概要文件数据实例之间没有区别关系,因此您的结果集将是。。。“丑死了!”史蒂夫波特——我以为进来很慢。这几个zip可能超过100个。@kris-我需要在这些列上进行两个匹配:field_id和value。如何在不生成表别名的情况下执行此操作?为什么要使用子查询?如果第二个子查询有一行,那么它将始终计算为true。。。你不会得到这些结果…只是概要文件数据中满足第一个标准的所有内容。如果第二个子查询返回null,则不会得到任何结果。这是我对OP指定的条件的理解。如果邮政编码在值的范围内,并且国家/地区在逻辑上为“美国”,则两者都必须为true才能满足其条件。如果相关用户id在邮政编码列表中,则第一个子句将为eval true;如果相关用户id在美国,则第二个子句将为eval true。当两个子句的值都为true时,它满足指定的条件。@magicmike-只有一个表,所以我需要不同的排序。您的第一个示例非常有效。谢谢你解释我们为什么加入。顺便说一句,我对否决票有点困惑,因为我的答案是第一个,甚至在任何编辑之前都是正确的(@KrisRobison我重新格式化了SQL,以便你可以看到它们是相关的子查询,你现在知道我正确地解释了OPs问题)请再次单击“下一票”按钮,删除下一票。或者,请大胆地评论为什么正确、明确的答案需要下一票。邮政编码不是特定于国家的。许多国家使用5位数格式()。@kris-我需要两个子句都是真的,而不是一个或另一个。