MySQL根据同一个表上的多个AND条件选择用户ID

时间:2017-11-16 10:03:40

标签: mysql

我想根据multiple和condition从单个表中选择一个用户ID。

UserID   FieldID  Value
-----------------------------------
1        51         Yes 
1        6          Dog 
2        6          Cat
1        68         TX  
1        69         78701
2        68         LA     

我试图用简单的词语表达:

如果用户搜索德州或78701, 选择userId where(68 = TX OR 69 = 78701)AND(51 = yes)AND(6 = Dog)

这应返回用户ID 1.

这是我尝试过的,但返回null。

SELECT user_id FROM `metadata` 
WHERE ( (`field_id` = '68' AND value LIKE '%TX%') 
   OR (`field_id` = '69' AND value LIKE '%78701%') ) 
   AND `field_id` = '51' AND value = 'Yes'
   AND `field_id` = '6' AND value = 'Dog'

4 个答案:

答案 0 :(得分:3)

您可以将GROUP BYHAVING子句一起使用,该子句使用多个条件聚合

SELECT UserID
FROM metadata
GROUP BY UserID
HAVING SUM(field_id = '68' AND value LIKE '%TX%' OR
           field_id = '69' AND value LIKE '%78701%') >= 1

       AND

       SUM(field_id = '51' AND value = 'Yes') >= 1

       AND

       SUM(field_id = '6' AND value = 'Dog') >= 1

Demo here

说明:在MysQL中有一个布尔表达式,如

field_id = '51' AND value = 'Yes'

在为true时返回1,在为false时返回0。

此外,HAVING子句的每个谓词都应用于整个记录组,由GROUP BY定义。

因此,谓词:

SUM(field_id = '51' AND value = 'Yes') >= 1

就像说:只返回那些至少有一个(> = 1)记录的UserID

field_id = '51' AND value = 'Yes' -> true

答案 1 :(得分:0)

您的表结构类似于属性+值建模,它基本上将行的列拆分为单独的对,并且具有非常弱的类型的副作用。

正如您所指出的,这也可能使查询变得棘手,因为您必须推理多行才能理解原始数据模型。

一种方法可能是对一个主要的'采取意见。条件,然后通过推理碎片数据来应用其他条件,由用户ID加入:

SELECT DISTINCT m.user_id 
FROM `metadata` m
WHERE ((`field_id` = '68' AND value LIKE '%TX%') 
       OR (`field_id` = '69' AND value LIKE '%78701%'))
 AND EXISTS 
 (SELECT 1 
    FROM `metadata` m2 
    WHERE m2.user_id = m.user_id AND m2.field_id = '51' AND m2.value = 'Yes')
AND EXISTS 
  (SELECT 1 
     FROM `metadata` m3 
     WHERE m3.user_id = m.user_id AND m3.field_id = '6' AND m3.value = 'Dog');

然而,IMO,尝试重新构建表可能更好(并且理想情况下选择更好的属性描述作为列):

UserID   Field51  Field6 Field68  Field69
----------------------------------------
1        Yes      Dog     TX      78701
2        No       Cat     LA      NULL

这将使查询更加容易。

答案 2 :(得分:0)

这种方法通常比在每个标准上简单地LEFT JOIN表更慢,但它可以使问题更容易理解......

SELECT userid
     , MAX(CASE WHEN fieldid = 51 THEN value END) smoker
     , MAX(CASE WHEN fieldid =  6 THEN value END) favourite_pet
     , MAX(CASE WHEN fieldid = 68 THEN value END) state
     , MAX(CASE WHEN fieldid = 69 THEN value END) zip
  FROM eav
 GROUP
    BY userid;

您可以使用HAVING,或将其捆绑到子查询中以获得所需的结果。

答案 3 :(得分:0)

SELECT user_id FROM metadata 哪里     (field_id ='68'和值LIKE'%TX%')         或(field_id ='69'和值LIKE'%78701%')         AND(field_id ='51'和值='是')         AND(field_id ='6'AND value ='Dog');

我有点改变你的查询并尝试使用相同的,它输出为,user_id为1