2016-02-12 41 views
3

的名单上有4个表:如何获得类似项目

项目

+----+------+---------+-----+ 
| id | name | city_id | ... | 
+----+------+---------+-----+ 

属性

+----+------+-----+ 
| id | name | ... | 
+----+------+-----+ 

item_attribute

+----+---------+--------------+ 
| id | item_id | attribute_id | 
+----+---------+--------------+ 

城市

+----+------+-----+ 
| id | name | ... | 
+----+------+-----+ 

项目和属性具有多对多的关系。

项目只位于一个城市一个一对多


问:

我使用PHP(Laravel)。我如何才能在一个城市中获得具有相似属性的项目列表(带有限制)?属性列表永远不会等于2个项目。

是否可以使用MySQL查询?


例子:

| ItemName | Attributes   | City | 
+----------+-----------------------+------+ 
| Alpha | one, two, three, four | NY | 
| Beta  | five, six, seven  | NY | 
| Gamma | one, three, seven  | NY | 
| Delta | one, six, eight  | CA | 
| Epsilon | two, three, four  | NY | 
| Zeta  | ten, nine    | NY | 

我想选择类似物品Alpha,他们将是:GammaEpsilon因为它们具有相似的属性。

Delta将不会被选中,因为它位于另一个城市。

+0

您能否请您显示您的数据和您想要的结果数据。这将很容易查找您的要求。 –

+0

如果您使用的是Laravel,是否为这些实体创建了Eloquent模型并定义了它们各自的'hasOne','belongsTo','hasMany'等...关系?然后你可以加载你需要的数据而不需要任何查询。如果你还没有,请阅读以下内容:https://laravel.com/docs/5.1/eloquent – Latheesan

+0

@用户示例添加 – MurDaD

回答

1

如果你同时拥有ITEM_ID和city_id在经过:

SELECT i.name, 
      GROUP_CONCAT(a.name) attributes, 
      c.name 
    FROM items i 
    JOIN city c 
     ON c.id = i.city_id 
    JOIN item_attribute ia 
     ON ia.item_id = i.id 
     AND EXISTS (
     SELECT 1 
     FROM item_attribute ia1 
     JOIN item_attribute ia2 
      ON ia2.attribute_id = ia1.attribute_id 
      AND ia2.item_id = ia.item_id 
     WHERE ia1.item_id = :item_id /* Pass in item id variable */ 
      ) 
    JOIN attributes a 
     ON a.id = ia.attribute_id 
    WHERE i.city_id = :city_id /* Pass in city id variable */ 
GROUP BY i.name, c.name 

如果你只是想通过例子项目编号:(A有点草率,但应该工作)

SELECT i.name, 
      GROUP_CONCAT(a.name) attributes, 
      c.name 
    FROM items base 
    JOIN items i 
     ON i.city_id = base.city_id 
    JOIN city c 
     ON c.id = i.city_id 
    JOIN item_attribute ia 
     ON ia.item_id = i.id 
     AND EXISTS (
     SELECT 1 
     FROM item_attribute ia1 
     JOIN item_attribute ia2 
      ON ia2.attribute_id = ia1.attribute_id 
      AND ia2.item_id = ia.item_id 
     WHERE ia1.item_id = base.id 
      ) 
    JOIN attributes a 
     ON a.id = ia.attribute_id 
    WHERE base.id = :item_id /* Pass in item id variable */ 
GROUP BY i.name, c.name 

**更新**

订购:

... 
JOIN (
     SELECT ia2.item_id, COUNT(*) count 
     FROM item_attribute ia1 
     JOIN item_attribute ia2 
      ON ia2.attribute_id = ia1.attribute_id 
      AND ia2.item_id = ia1.item_id 
     /* AND ia2.id != ia1.id /* If you don't want the original item */ 
     WHERE ia1.item_id = base.id 
    GROUP BY ia2.item_id 
    ) similar 
    ON similar.id = ia.item_id 
... 
ORDER BY similar.count DESC 
+0

谢谢,那工作。但在存在的错误(SELECT 1 FROM item_attribute IA1 JOIN item_attribute IA2 ON ia2.attribute_id = ia1.attribute_id AND ia2.item_id = ia1.item_id WHERE ia1.item_id =:ITEM_ID/*转至项id变量* /) – MurDaD

+0

那么错误是什么?评论(我的phpmyadmin不喜欢他们)?你写了EXIST/EXISTS吗? – Arth

+0

我的意思是,“AND ia2.item_id = ia.id”mus被替换为“AND ia2.item_id = ia1.item_id” – MurDaD

0

可以在所有

SELECT I.name,I_A.name,city.name FROM attributes as A 
INNER JOIN item_attribute as I_A ON I_A.attribute_id = A.id 
INNER JOIN city ON I_A.id = city.id 
INNER JOIN items as I ON I.id = I_A.item_id 
WHERE <Your condition> 

执行INNER JOINS为了让您可以参考here 让我知道,如果我没有得到你的观点逗号分隔值。