Mysql 如何选择两列应在多行上匹配的不同行?

Mysql 如何选择两列应在多行上匹配的不同行?,mysql,sql,Mysql,Sql,我有一张这样的桌子: id | user_id | param_id | param_value 1 1 44 google 2 1 45 adTest 3 1 46 Campaign 4 1 47 null 5 1 48 null 6 2

我有一张这样的桌子:

id | user_id | param_id | param_value  
1      1          44          google
2      1          45         adTest
3      1          46         Campaign
4      1          47          null
5      1          48          null
6      2          44          google
7      2          45         adAnotherTest
8      2          46         Campaign2
9      2          47         null
10     2          48         null  
我想获取所有的用户id,其中(param_id=44和param_value=google)和(param_id=45和param_value=adTest)。所以上面的where子句应该只给出user_id=1,而不是user_id=2。他们都有参数id为44的google,但只有用户1在参数id=45时有参数值adTest

问题是n将来可能会添加更多参数。我需要找到一个动态查询。以下是我尝试过的:

SELECT DISTINCT up.user_id FROM user_params AS up

                    LEFT JOIN user_params AS upp ON up.id = upp.id

                    WHERE up.param_id IN (?,?) 

                    AND upp.param_value IN (?,?)

如果您想要优化,则应该在不需要左联接表扫描的情况下提供相同的结果(,感谢juergen d提供了部分内容)


请参阅演示

如果要优化,则应在不需要左联接表扫描的情况下提供相同的结果(感谢juergen d提供零件

请参见另一种方式的演示:

SELECT  -- DISTINCT 
    up1.user_id 
FROM 
    user_params AS up1
  JOIN
    user_params AS up2 
      ON up1.user_id = up2.user_id
WHERE
    up1.param_id = 44 AND up1.param_value = 'google'
  AND 
    up2.param_id = 45 AND up2.param_value = 'adTest' ;
如果对
(用户id,参数id)

为了提高效率,请在
上添加索引(参数id、参数值、用户id)


您正在处理的问题称为“关系划分”,这里@Erwin Brandstetter给出了一个很好的答案:,提供了许多编写此类查询的方法以及性能测试

这些测试是在Postgres中完成的,因此有些查询甚至没有在MySQL中运行,但至少有一半在MySQL中运行,而且许多查询的效率与之类似。

另一种方式:

SELECT  -- DISTINCT 
    up1.user_id 
FROM 
    user_params AS up1
  JOIN
    user_params AS up2 
      ON up1.user_id = up2.user_id
WHERE
    up1.param_id = 44 AND up1.param_value = 'google'
  AND 
    up2.param_id = 45 AND up2.param_value = 'adTest' ;
如果对
(用户id,参数id)

为了提高效率,请在
上添加索引(参数id、参数值、用户id)


您正在处理的问题称为“关系划分”,这里@Erwin Brandstetter给出了一个很好的答案:,提供了许多编写此类查询的方法以及性能测试


这些测试是在Postgres中完成的,因此有些查询甚至没有在MySQL中运行,但至少有一半在MySQL中运行,而且效率在许多查询中都是相似的。

Ty对于快速答案,briliantNice+1发布了一个基于您的快速答案的升级,briliantNice+1,并根据您的回答发布了一个升级。此通知已被删除:),ty。但是你的答案并没有那么有效,因为查询是动态的,就像我在问题中说的那样。如果我添加越来越多的连接将不是一个好的解决方案。接受的解决方案最适合动态查询(要匹配的许多参数id参数值对),但可能不太好,因为每次都必须构建不同的查询,因此需要动态解决方案。但是你真的测试过效率吗,或者你只是在猜测?我的估计是,联接越多,此查询的效率就越高。使用12++联接的查询什么时候有效看这个(7-join):。从400秒下降到0.0318秒,并进行适当的索引。当您加入同一个表时,mysql引擎不是再次读取所有数据吗?如果可能的话,最好只看一次或少看几次。Distinct已被删除:),用于通知。但是你的答案并没有那么有效,因为查询是动态的,就像我在问题中说的那样。如果我添加越来越多的连接将不是一个好的解决方案。接受的解决方案最适合动态查询(要匹配的许多参数id参数值对),但可能不太好,因为每次都必须构建不同的查询,因此需要动态解决方案。但是你真的测试过效率吗,或者你只是在猜测?我的估计是,联接越多,此查询的效率就越高。使用12++联接的查询什么时候有效看这个(7-join):。从400秒下降到0.0318秒,并进行适当的索引。当您加入同一个表时,mysql引擎不是再次读取所有数据吗?如果可能的话,只读一次或少读几次不是更好吗?
SELECT  -- DISTINCT 
    up1.user_id 
FROM 
    user_params AS up1
  JOIN
    user_params AS up2 
      ON up1.user_id = up2.user_id
WHERE
    up1.param_id = 44 AND up1.param_value = 'google'
  AND 
    up2.param_id = 45 AND up2.param_value = 'adTest' ;