【问题标题】:MySQL attribute databaseMySQL属性数据库
【发布时间】:2011-06-23 11:42:18
【问题描述】:

我有一个属性数据库。每个属性值都存储在一个带有其父属性 ID 的表中。

在一个独立的表中,我会编写一个提取数据的 SQL 语句

WHERE username = '' AND domain = ''  

在属性表中,因为每个值都存储为单独的行,所以我不能这样做。我有一个连接,可以让我带回一个值 + 结果(见下文),但是我需要一个基于2个标准如上图..

SELECT upa.value, up.status, u.status
  FROM user_product up, product_attribute pa, product p, user u, user_product_attribute upa

 WHERE pa.attribute_name = 'username'
   AND pa.product_attribute_id = upa.product_attribute_id
   AND pa.product_id = p.product_id
   AND u.user_id = up.user_id
   AND up.user_product_id = upa.user_product_id

   AND p.product_name = 'email'
   AND upa.value      = 'exampleuser'

我想我需要以某种形式再次加入上述能力?任何输入都会有所帮助..

谢谢

【问题讨论】:

    标签: sql mysql join normalization


    【解决方案1】:

    请不要使用隐式连接语法。需要第二组连接才能获得第二个属性。

    SELECT upa1.value, upa2.value, up1.status, u1.status 
      FROM product p
        /* These joins get attribute/value for 'username' attribute */
        INNER JOIN product_attribute pa1
          ON p.product_id = pa1.product_id
            AND pa1.attribute_name = 'username'
        INNER JOIN user_product_attribute upa1
          ON pa1.product_attribute_id = upa1.product_attribute_id
        INNER JOIN user_product up1
          ON upa1.user_product_id = up1.user_product_id
        INNER JOIN user u1
          ON up1.user_id = u1.user_id 
        /* These joins get attribute/value for 'domain' attribute */  
        INNER JOIN user_product_attribute upa2 
          ON upa1.user_product_id = upa2.user_product_id
        INNER JOIN product_attribute pa2
          ON upa2.product_attribute_id = pa2.product_attribute_id            
            AND pa2.attribute_name = 'domain'
      WHERE p.product_name = 'email'
    

    【讨论】:

    • 嗨,谢谢您的意见。但是我看到的问题是,可能有很多域,而不仅仅是一个.. 所以像这样的加入会带回 1:* 而不是 1 :1..
    • 如果给定产品有多个域,您如何决定要返回哪个域?换句话说,您还会使用哪些其他标准来打破多个域之间的联系?
    • @Lee:根据您的 cmets 将我的答案更新为 @ar 关于常见的 user_product_id 值。
    • 谢谢你,辛苦了。。我也可以看出我在哪里想错了。
    【解决方案2】:

    您需要将所有连接重复两次才能获得这两个属性。如果您一次需要超过 2 或 3 个属性,这并不漂亮。

    SELECT upa.value, up.status, u.status
    FROM user_product up
    JOIN user u    ON u.user_id = up.user_id
    
    -- Join to get attribute 'username'
    JOIN user_product_attribute upa1 ON up.user_product_id = upa1.user_product_id
    JOIN product_attribute pa1 ON pa1.product_attribute_id = upa1.product_attribute_id
    JOIN product p1                  ON pa1.product_id = p1.product_id
    
    -- Join to get attribute 'domain'    
    JOIN user_product_attribute upa2 ON up.user_product_id = upa2.user_product_id
    JOIN product_attribute pa2 ON pa2.product_attribute_id = upa2.product_attribute_id
    JOIN product p2                  ON pa2.product_id = p2.product_id
    
    WHERE pa1.attribute_name = 'domain'
      AND p1.product_name = 'email'
      AND upa1.value      = 'exampledomain.com'
    
      AND pa2.attribute_name = 'username'
      AND p2.product_name = 'email'
      AND upa2.value      = 'exampleuser'
    ;
    

    【讨论】:

    • Product 对两组属性 (product.product_name = 'email') 都很常见,因此该表只能在查询中引用一次。
    • 嗨,谢谢您的意见。但是我看到的问题是,可能有很多域,而不仅仅是一个.. 所以像这样的加入会带回 1:* 而不是 1 :1..
    • @Lee,在这种情况下,您需要使用要用于选择记录的逻辑来更新您的问题。例如,您是否要搜索任何关联域记录匹配的记录或其他逻辑?
    • 值通过 user_product_attribute 表中的 user_product_id 链接到用户产品。因此,域 + 用户名组合应该共享相同的 user_product_id 值。
    猜你喜欢
    • 2015-09-08
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 2011-11-06
    • 2016-08-07
    • 2020-07-07
    • 1970-01-01
    相关资源
    最近更新 更多