【问题标题】:MySQL Query: Multiple joins on the same field returning multiple categories - HOW?MySQL 查询:同一字段上的多个连接返回多个类别 - 如何?
【发布时间】:2013-06-13 15:32:02
【问题描述】:

我们有一个包含大约 40000 个 ID 的表 - 其中一些 ID 是其他 ID 的父级(随后其中一些是另一个表中其他 ID 的父级)。我想使用魔法、持久性和一些连接来通过查询包含所有子 ID 的字段(称为排列)来确定哪些类别是相关的。

所以它的工作方式是类别表:

id       name               arrange
16       Alarms             c,119|c,117|c,4607|c,3366|c,709|c,4204|c,624|c,626|c,625|c,4203|c,4201|c,4202
119      Carbon Monoxide    i,21434|i,272|i,274|i,28451

Products 表然后有第 i 个,来自排列的项目

id       name
272      Aico EI205ENA
274      AICO EI225EN

基本上,我正在对第三个订单表运行查询,并希望使用连接创建一个表,如下所示:

order date    id    name       id    name               id    name             quantity    price
13-06-2013    16    Alarms     119   Carbon Monoxide    272   Aico EI205ENA    2           10.00

目前我有:

 select * from cart c
 join prods p on p.id = c.item
 where order_status = ''
 and date_ordered != '0000-00-00'
 order by date_added desc;

我现在想添加第一个示例中的类别的简单连接,到底如何查询数组以获得我想要的?

(如果对我们有 3 个表有帮助,我对购物车、产品和类别感兴趣)。

提前致谢!

【问题讨论】:

  • 不!!!!见归一化!!
  • 当我看到您的arrange 列如何存储数据时......我哭了。为你。因为你用那个打了自己的脚:(
  • 第一次打破您的 Category 表,以简化 arrange 列。为此使用规范化。
  • 虽然可以进行这样的连接(使用 FIND_IN_SET 的一些丑陋技巧,或者通过在 SQL 中手动拆分数组),但规范化数据库要好得多。将排列字段拆分到另一个表中,每个名称都有多行,一个用于“数组”中的每个值。这可以很容易地连接起来。如果你真的想保持原样,那么给定表定义我可能会提出一个查询,但目前我可以看到你的示例数据 id 272 如何与警报和一氧化碳相关

标签: mysql join


【解决方案1】:

我现在已经意识到这些表是如何连接在一起的。

您想做的事情可以通过以下方式实现。它会很慢,我把它放在这里的主要原因是为了展示它是多么令人讨厌和不可读,以鼓励规范化数据库。

SELECT * 
FROM cart c
INNER JOIN prods p 
ON p.id = c.item
INNER JOIN Category z1
ON FIND_IN_SET(CONCAT('i-', p.id), REPLACE(REPLACE(z1.arrange, 'i,', 'i-'), '|', ',')) > 0
INNER JOIN Category z2
ON FIND_IN_SET(CONCAT('c-', z1.id), REPLACE(REPLACE(z2.arrange, 'c,', 'c-'), '|', ',')) > 0
WHERE order_status = ''
AND date_ordered != '0000-00-00'
ORDER BY date_added DESC

FIND_IN_SET 是一个在逗号分隔列表中查找值的函数。这是获取您的分隔列表,更改所有出现的 i, 并将它们更改为 i- 然后更改所有出现的 | 并更改他们用逗号。然后它在生成的逗号分隔列表中查找与 id 连接的 i- 。然后再次对类别进行相同的连接以获得父类别的匹配。

【讨论】:

  • Kickstart - 你是对的,它非常慢 - 但仅仅是因为我们糟糕的数据库布局。我将对它的正常化进行一些调查,遗憾的是我认为我们现在没有足够的资源来担心它。不过,非常感谢您的帮助,今天第一次使用 FIND_IN_SET 并到达某个地方但不远。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多