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

时间:2019-06-28 02:07:17

标签: mysql

我知道这类似于this question,但是仍然没有有效的答案,我将尽力进行解释。

所以我有3个表,分别是membermeta_namemeta_value。我想您已经知道它们之间的关系了。例如,假设我有这些行:

member表:

memberID | name
   1     | john

meta_name表:

meta_nameID | name
     1      | address
     2      | jobTitle

meta_value表:

meta_valueID | meta_nameID | memberID | value
     1       |      1      |    1     | California
     2       |      2      |    1     | Manager

因此John有两个元数据,分别是address和jobTitle。元数据存储在meta_value表中,并且mete_value表在meta_name表中具有标识符。这只是一个基本的元数据系统。

现在的问题是,我如何才能在meta_value表上获得满足两个或多个条件的成员?像是“让在加利福尼亚有住址并获得工作职位的会员作为经理”?

我已经尝试过以下查询:

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_value表数据。我只想让满足条件的成员。

2 个答案:

答案 0 :(得分:1)

有许多不同的选项。 直接:

else
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
    *
FROM
    member
WHERE
    memberID IN (
        SELECT
            memberID
        FROM
            meta_value
        WHERE
                meta_value.meta_nameID = 1
            AND meta_value.value = '3'
    )
    AND memberID IN (
        SELECT
            memberID
        FROM
            meta_value
        WHERE
                meta_value.meta_nameID = 2
            AND meta_value.value = 'Jonggol'
    )

但是,我想指出的是,此类数据库模式仅应用于存储需要过滤的数据。

答案 1 :(得分:1)

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

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表,稍后分别加入该地址以获取地址和jobTitle以获取职位。这将为您提供一个以address和jobTitle作为列的成员级别表以便在后续查询中轻松使用)

WITH tmp AS
(SELECT * FROM meta_value mv INNER JOIN meta_name mn ON mv.meta_nameID=mn.meta_nameID)
SELECT member.name , add.value , job.value
FROM member 
        LEFT JOIN (SELECT * FROM tmp WHERE name='address') add ON member.memberID = add.memberID
        LEFT JOIN (SELECT * FROM tmp WHERE name='jobTitle') job ON member.memberID = job.memberID
WHERE add.value  = 'required address' AND add.job.value ='required job title'