如何通过线与连接查询值?

给定两个表和值:

Tables People- Columns: [ID]PK Name Field - Columns: [ID FieldName]PK FieldValue Values People ID Name 1 Mary 2 John 3 Tony Field ID FieldName FieldValue 1 Age 20 1 Country USA 2 Age 21 2 Country USA 3 Age 20 3 Country USA

我想一个查询,让我从美国的人的名字,并有20岁。 结果应该是玛利亚和托尼。

SELECT name FROM people p INNER JOIN field f ON f.ID = f.ID WHERE (FieldName = 'Age' AND FieldValue= '20') OR (FieldName = 'Country' AND FieldValue= 'USA'));

与该查询的问题是“OR”之间的where子句。 我会得到的,而不是只有玛利亚和托尼的3人。 如果我使用了AND,没有结果返回。

你有一些建议吗?

提前致谢 :)

--------------解决方案-------------

那这个呢?

SELECT name
FROM people p
JOIN field fAge ON p.ID = fAge.ID
AND fAge.FieldName = 'Age'
JOIN field fCountry ON p.ID = fCountry.ID
AND fCountry.FieldName = 'Country'
WHERE fAge.FieldValue = '20'
AND fCountry.FieldValue = 'USA'

因此本质上处理国家和年龄数据作为单独的表。 因为它似乎该field表用于存储不同类型的数据。

它可能是有用的具有不同的数据库Views此表上对于每个类型的数据。 这将进一步简化上述查询。

你在这里做了什么,不幸的是,实现实体 - 属性 - 值(EAV)反模式。 (反模式是一个奇特的字“的东西,通常是一个坏主意。”),这是一般柜台SQL最佳实践有一个“场”的表像你这样的,这就是为什么它的名字命名的反模式。 “实体”指的是你的ID列(或者,由协会,一个人记录),“属性”对应的字段名,和“价值”fieldValue方法。

欲了解更多信息,看看这个优秀组幻灯片(这应该直接链接到EAV的部分;如果没有,则跳到滑动16)。

解决的办法是重构你的数据库中,以便年龄和国家都在你的人物表中的字段。 然后,一个更简单的查询将有可能: SELECT name FROM people WHERE Age = 20 AND Country = 'USA';

你不说你是否考虑和拒绝了“标准”设计,将姓名,年龄,以及国家在一个表中。 这将使大大简化查询,并类型和年龄值范围内保护以及FK / PK保护的国家价值观。

如果你有一个积极的理由使用键/值的方式,那么你有三种选择查询:

  1. 加入键/值表中查询一次你要搜索的每一项(见菲利普的回答,上文)。
  2. 使用在存在的条件:

    SELECT Name FROM People WHERE
    EXISTS (SELECT * FROM Field WHERE ID = People.ID AND FieldName = 'Country' AND Fieldvalue = 'USA')
    AND EXISTS (SELECT * FROM Field WHERE ID = People.ID AND FieldName = 'Age' AND Fieldvalue = '20')
  3. 使用某种相交,或者在您的SQL方言支持SUBTRACT操作符。
分类:SQL 时间:2012-02-25 人气:0
本文关键词: SQL,加入
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.435 (s). 10 q(s)