【问题标题】:How to get a list of similar items如何获取相似项目的列表
【发布时间】:2016-02-12 11:15:35
【问题描述】:

我有 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 不会被选中,因为它位于另一个城市。

【问题讨论】:

  • 能否请您显示您的数据和您想要的结果数据。这样很容易查找您的要求。
  • 如果您使用 Laravel,您是否为这些实体创建了 Eloquent 模型并定义了它们各自的 hasOnebelongsTohasMany 等...关系?然后您可以加载您需要的数据而无需任何查询。如果您还没有,请阅读以下内容:laravel.com/docs/5.1/eloquent
  • @Latheesan 是的,添加了 Eloquent 模型,但是。请仔细阅读任务。 Laravel 不支持我需要的功能。或者如果有,请在回答中告诉我
  • 需要一个“相似”的定义..你想要一个特定城市的所有项目的所有属性吗?
  • @Arth 请参阅示例。是的,它将是具有至少一个相等属性的项目列表

标签: php mysql list laravel group-by


【解决方案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

如果您只想传递示例项目 id:(有点草率,但应该可以)

   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 

【讨论】:

  • 谢谢,工作。但是 EXIST 中的错误(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 变量 */)
  • 那么错误是什么?评论(我的 phpmyadmin 不喜欢它们)?你写过 EXIST/EXISTS 吗?
  • 我的意思是,“AND ia2.item_id = ia.id”必须替换为“AND ia2.item_id = ia1.item_id”
  • @MurDaD 这听起来不对,它必须与外部记录有关,否则它将始终返回 true
  • 比,这行出错了,因为它说“ia.id - column not found”,但它就在那里。明确地。但我不明白,为什么我们需要这张表的 id?这是服务表
【解决方案2】:

你可以全部执行INNER JOINS

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>

要获取逗号分隔值,您可以参考here 如果我不明白你的意思,请告诉我。

【讨论】:

    猜你喜欢
    • 2011-07-19
    • 2014-01-24
    • 1970-01-01
    • 1970-01-01
    • 2015-02-23
    • 2019-03-22
    • 1970-01-01
    • 2021-03-15
    • 2019-05-09
    相关资源
    最近更新 更多