Mysql 如何从满足元数据表上两个或多个条件的表中获取数据?

Mysql 如何从满足元数据表上两个或多个条件的表中获取数据?,mysql,Mysql,我知道这类似于,但仍然没有有效的答案,我将尝试更好地解释 所以我有三个表,分别是member,meta\u name,和meta\u value。我想你已经知道他们之间的关系了。例如,假设我有以下行: 成员表格: memberID | name 1 | john meta_nameID | name 1 | address 2 | jobTitle meta_valueID | meta_nameID | memberID | value

我知道这类似于,但仍然没有有效的答案,我将尝试更好地解释

所以我有三个表,分别是
member
meta\u name
,和
meta\u value
。我想你已经知道他们之间的关系了。例如,假设我有以下行:

成员
表格:

memberID | name
   1     | john
meta_nameID | name
     1      | address
     2      | jobTitle
meta_valueID | meta_nameID | memberID | value
     1       |      1      |    1     | California
     2       |      2      |    1     | Manager
meta\u name
表格:

memberID | name
   1     | john
meta_nameID | name
     1      | address
     2      | jobTitle
meta_valueID | meta_nameID | memberID | value
     1       |      1      |    1     | California
     2       |      2      |    1     | Manager
meta_值
表:

memberID | name
   1     | john
meta_nameID | name
     1      | address
     2      | jobTitle
meta_valueID | meta_nameID | memberID | value
     1       |      1      |    1     | California
     2       |      2      |    1     | Manager
所以John有两个元数据,地址和职位。元数据存储在
meta_值
表中,
mete_值
表在
meta_名称
表中有标识符。这只是一个基本的元数据系统

现在的问题是,如何获得满足
meta_值
上两个或多个条件的成员?比如,“让会员在加利福尼亚州有地址,并有经理的头衔”

我尝试了以下查询:

SELECT * FROM member JOIN meta_value ON member.memberID = meta_value.memberID WHERE (meta_nameID = '1' AND value = '3') AND (meta_nameID = '2' AND value = 'Jonggol')
我知道这是一个丑陋的不可行的问题,但我希望这能帮助你理解我将要实现的目标。谢谢


注意:我实际上不需要
meta_值
表数据。我只想获得满足条件的会员。

有许多不同的选择。 直截了当:

SELECT
    *
FROM
    member
WHERE
    EXISTS (
        SELECT
            *
        FROM
            meta_value
        WHERE
                meta_value.memberID = member.memberID
            AND meta_value.meta_nameID = 1
            AND meta_value.value = '3'
    )
    AND EXISTS (
        SELECT
            *
        FROM
            meta_value
        WHERE
                meta_value.memberID = member.memberID
            AND meta_value.meta_nameID = 2
            AND meta_value.value = 'Jonggol'
    )
另一种方式:

SELECT
      member.*
    , SUM(IF((meta_value.meta_nameID = 1 AND meta_value.value = '3') OR (meta_value.meta_nameID = 2 AND meta_value.value = 'Jonggol'), 1, 0)) AS x
FROM
    member
    INNER JOIN meta_value ON (
        meta_value.memberID = member.memberID
    )
GROUP BY
    member.memberID
HAVING
    x = 2

但是,我想指出的是,这种DB模式应该只用于存储需要过滤的数据。

您需要使用子查询。尝试以下查询以选择具有特定地址和职务的成员。

SELECT member.name
FROM member
WHERE 
    memberID IN 
        (SELECT DISTINCT memberID 
        FROM meta_value
        WHERE meta_nameID IN
                (SELECT DISTINCT meta_nameID FROM meta_name WHERE name='address') 
                AND value='California')
    AND memberID IN
        (SELECT DISTINCT memberID 
        FROM meta_value
        WHERE meta_nameID IN 
                (SELECT DISTINCT meta_nameID FROM meta_name WHERE name='jobTitle') 
                AND value='Manager')
您还可以尝试使用with子句进行较小的查询:

(这里我们创建一个tmp表,该表同时包含地址和职务,稍后分别连接地址以获得just address和jobTitle以获得just job title。这将为您提供一个成员级表,其中地址和职务为列,以便在任何后续查询中使用)


第一个选项给了我一些错误。但我尝试了第二种选择,效果很好。谢谢真奇怪。我将其复制/粘贴到我的客户机中,1和2查询可以正常工作。将“3”改为“California”,将“Jonggol”改为“Manager”,并找到了“john”。在上一个查询中,它是错误的(我输入了'meta_nameID.value'而不是'meta_value.value')。修正了。这同样有效!我想我会学到更多关于子查询的知识。我要学习这个话题。谢谢