如何选择表a中的所有行,这些行具有表b中给出的n个特征

时间:2011-09-16 19:24:43

标签: mysql select

我正在制作一个租房子的网页。

出版物存储在这样的表中

ta_publications
+---+-------------+------+
|id |    name     | date |
+---+-------------+------+
| 1 | name_001    |  ... |
| 2 | name_002    |  ... |
| 3 | name_003    |  ... |
+---+-------------+------+

我有不同的出版物,有“卫星电视”,“洗衣清洁”等“功能”。

这些功能将来可能会发生变化,我希望能够添加/删除/修改它们,因此我将它们存储在表格的数据库中。

ta_feature_types
+---+-------------+
|id | name        |
+---+-------------+
| 1 | Internet    |
| 2 | Wi-Fi       |
| 3 | satelital tv|
+---+-------------+

与使用表格的出版物相关

ta_features
+---+-------------+----------------+
|id |   type_id   | publication_id |
+---+-------------+----------------+
| 1 |      1      |       1        |
| 2 |      2      |       1        |
| 3 |      3      |       1        |
+---+-------------+----------------+

我认为这很容易理解;有一个名为name_001的出版物,它有互联网,Wi-Fi和卫星电视。

我的问题是:我需要能够有效地搜索和选择具有某些功能的所有出版物(房屋)。例如,所有具有互联网,wifi和“允许宠物”功能的出版物。

我刚才想出了另一个问题:当用户喜欢一个出版物时,比如“house_003”,我该如何获得它所具有的功能列表?

3 个答案:

答案 0 :(得分:2)

如果您想按功能名称获取出版物:

SELECT p.*
FROM ta_publications p
JOIN ta_features f ON f.publication_id = p.id
JOIN ta_feature_types t ON f.type_id = t.id
WHERE t.name = ? -- feature name

如果您已经知道功能 ID

SELECT p.*
FROM ta_publications p
JOIN ta_features f ON f.publication_id = p.id
WHERE f.type_id = ? -- feature ID

编辑:要获取与多个功能ID 所有匹配的所有出版物:

SELECT p.id, p.name
FROM pub p
JOIN pub_feat pf ON pf.pub_id = p.id
WHERE pf.feat_id IN ? -- list of feature IDs, e.g. (1,2,3)
GROUP BY p.id, p.name HAVING COUNT(*) = ? -- size of list of feature IDs, e.g. 3

按发布ID获取所有功能(名称,我假设):

SELECT t.name
FROM ta_feature_types t
JOIN ta_features f ON f.type_id = t.id
JOIN ta_publications p ON f.publication_id = p.id
WHERE p.id = ? -- publication ID

有关您的架构的一些注意事项:

  • 正如我在上面评论的那样,除了出版物可以具有倍数相同的特征时,您不需要ta_features表中的ID列,例如“2x Wi-Fi”

  • 您的表格名称令人困惑,我建议您重命名

    • ta_featuresta_publication_features(或ta_pub_features)和
    • ta_feature_typesta_features
  • 出于性能原因,您应该在上述JOIN条件中使用的所有列上创建索引(使用此处的原始表名称):

    • ta_publications(id)
    • ta_features(type_id, publication_id)
    • ta_feature_types(id)

答案 1 :(得分:1)

如果用户选择多个功能,请使用IN关键字和发布的所有功能列表:

SELECT p.*
FROM ta_publications p
WHERE '1' in (select type_id from ta_features where publication_id = p.id)
AND '2' in (select type_id from ta_features where publication_id = p.id)
AND '3' in (select type_id from ta_features where publication_id = p.id)

您可以使用所选服务器语言的循环生成上述内容。即

SELECT p.*
FROM ta_publications p
WHERE 1=1
//START SERVER LANGUAGE
for (feature in featuresArray){
    print("AND '$feature' in (select type_id from ta_features where publication_id = p.id)");
}
//END SERVER LANGUAGE

答案 2 :(得分:0)

我认为你想要的是一个子查询:

select a.* 
from ta_publications as a
where '1' in (select type_id from ta_features where publication_id=a.id)

将“1”替换为您想要的任何其他功能号。

第二个问题。一个简单的查询应该这样做:

select type_id 
from ta_features
where publication_id=[[[id that someone likes]]]