防止mysql中的重复加入视图
Posted
技术标签:
【中文标题】防止mysql中的重复加入视图【英文标题】:Prevent Duplicates in mysql join in a view 【发布时间】:2016-08-22 22:10:49 【问题描述】:我有两张桌子。一个是物品,一个是 ebay 列表。 给定项目可以有多个 ebay 列表。
我有一个视图,它从包括 ebay 表在内的多个表中聚合(左连接)一堆定价信息。
e.custom_label
将以i.id
开头,但不保证完全匹配。
SELECT i.id, i.price AS master_price, e.price AS ebay_price
FROM items i
LEFT JOIN ebay e ON ((e.custom_label LIKE CONVERT(concat(i.id,'%') using latin1)))
这大大简化了,但应该描述问题。
正如预期的那样,由于有多个与 ON 语句匹配的 ebay 列表,你会得到类似
item master_price ebay_price
1234 29.95 29.95
1235 36.95 29.95
1235 36.95 29.95
通常我们会使用子查询来代替连接中的ebay
表来过滤掉重复项,但是由于这是一个视图,所以我们不能。这使我们无法在连接表上进行分组。有没有其他方法可以过滤掉重复项,以使基表可以从视图中编辑?
对于这种观点,获得价格(并且知道该产品在 ebay 上列出)比确保所有 ebay 价格相同更重要,所以我只需要一行。 UI 依赖于每个项目只有一行。
【问题讨论】:
为什么不能在视图中使用子查询?你试过了吗?长话短说,你试过GROUP BY item
吗?
是的。 (即:***.com/questions/17983379/…)
在您在 mysql 中创建视图的道路上走得太远之前,我建议您确保您了解大型表的性能影响...来自外部查询的谓词不会被推入视图查询,并且视图查询的结果始终被具体化为没有索引的派生表。 (最新版本的 MySQL 部分解决了派生表上缺少索引的问题。)危险,Will Robinson。危险!
a) 您是否尝试过 group by item
b) 您可以在视图中使用子查询,但出于所有目的 - 子查询与 JOIN
完全相同 - 因此,无论您可以通过子查询来实现——你可以用JOIN
来做同样的事情。 c) 你没有指定使用的 MySQL 版本 d) 如果那些 ebay 价格对于同一个项目总是相同的,你为什么首先将它多次存储在表中?唯一索引和 ON DUPLICATE KEY UPDATE
确实很神奇(甚至 INSERT IGNORE
也会帮助你)。
@N.B.向整个查询添加 group by 确实可以解决问题,但会破坏编辑。不能使用 group by 的视图来更新表格。
【参考方案1】:
我认为您可以在 SELECT 列表中使用相关子查询,因为您只提取一列。 (我将在我对这个问题的评论中重复警告......危险,威尔罗宾逊,危险!)
我没有把我的大脑包裹在连接谓词上,它应该做什么......
i.id = ((e.custom_label LIKE CONVERT(concat(i.id,'%') using latin1)))
e.custom_label LIKE foo
将返回一个布尔值。值为 TRUE、FALSE 或 NULL。在数字上下文中评估,布尔值将是 1、0 或 NULL。然后获取该结果,并与id
列进行相等比较...我不明白,对于除 1 或 0 之外的任何 id 值,整个表达式将如何计算为 TRUE。
但话又说回来,custom_label
第一部分的整个匹配业务对我来说似乎很奇怪。
ebay 中的哪些行应该与 item.id 的值匹配,如下所示:
item.id
-------
12
123
ebay.custom_label
-----------------
122
123
1234
12345
但除了整个业务......
我不确定为什么 SELECT 列表中的相关子查询对您不起作用。举个例子。 (在相关子查询的 WHERE 子句中使用您需要的任何“匹配条件”。)
SELECT i.id
, i.price AS master_price
, ( SELECT e.price
FROM ebay e
WHERE e.custom_label REGEXP CONCAT('^',i.id)
LIMIT 1
) AS ebay_price
FROM items i
存储的视图定义可能存在一些限制。 (在存储视图定义方面没有太多经验。由于可能引入的各种问题,我们只是避免创建存储视图定义。这些问题可能会比存储视图定义解决的问题要大得多。)
【讨论】:
哎呀,实际加入是LEFT JOIN cffhub_channel_ebay e on((e.custom_label like convert(concat(p.posid,'%') using latin1)))
...我在简化时设法搞砸了。谢谢你的回答,我试试看。以上是关于防止mysql中的重复加入视图的主要内容,如果未能解决你的问题,请参考以下文章