我有以下架构:
id | order_ref | description | price
目前我有以下重复问题:
1 | 34567 | This is the description | 19.99
2 | 34567 | This is the description | 13.99
这是由于我导入的数据,每个项目的描述都是重复的。有没有办法可以保留第一行,然后将后续(最多约20行)的描述更新为'AS ABOVE'?
1 | 34567 | This is the description | 19.99
2 | 34567 | - AS ABOVE - | 13.99
由于
-------修订版
UPDATE documents_orders_breakdown
SET `desc` = '- AS ABOVE -'
WHERE NOT id IN (SELECT id
FROM documents_orders_breakdown AS D
WHERE D.`desc` <> `desc`
ORDER BY D.id
LIMIT 1)
但这会返回[Err] 1235 - 这个版本的MySQL还不支持'LIMIT&amp; IN / ALL / ANY / SOME子查询'
--------修订版
UPDATE documents_orders_breakdown
SET `desc` = '- AS ABOVE -'
WHERE NOT id IN (SELECT MIN(id)
FROM documents_orders_breakdown AS t
WHERE t.`desc` = `desc`)
现在返回[Err] 1093 - 您无法在FROM子句中为更新指定目标表'documents_orders_breakdown'
答案 0 :(得分:1)
如果这是一次性的事情,性能不是一个大问题。您可以对SELECT值为1的SELECT未返回的所有记录运行UPDATE。
UPDATE the_table
SET description = '- AS ABOVE -'
WHERE NOT id IN (SELECT id
FROM the_table t
WHERE t.description = the_table.description
ORDER BY t.id
LIMIT 1)
此查询假定您要保留id为第一位的记录的描述(因此为ORDER BY)。
由于您无法在子查询中使用LIMIT,因此可以使用聚合函数MIN来解决这个问题:
UPDATE the_table
SET description = '- AS ABOVE -'
WHERE NOT id IN (SELECT MIN(id)
FROM the_table t
WHERE t.description = the_table.description)
(我们希望您可以混合使用MIN和子查询;)
显然是you can't SELECT from the table you're UPDATEing in MySQL。解决方法是使用隐式临时表。这对性能不利,但是,再次,鉴于这是一次性的事情,这不是一个大问题。
UPDATE the_table
SET description = '- AS ABOVE -'
WHERE NOT id IN (SELECT m FROM (SELECT MIN(id) AS m
FROM the_table t
WHERE t.description = the_table.description) AS temp)
答案 1 :(得分:0)
关系日期基础没有后续的概念。表中的记录没有任何特定顺序。如果您未在SELECT
查询中指定订单,则必须假定按照您不期望的顺序检索记录。
答案 2 :(得分:0)
Oswald关于行的排序(或缺少)的评论非常重要。您没有受限,期间,从此表中选择的未排序行将按您期望的顺序排列。这意味着除非您每次都按照表格顺序指定现有,否则即使这不能反映现实情况,也可以标记为“如上所述”。此外,到目前为止,所提供的解决方案都没有适当地处理任何无序记录 总的来说,这听起来更像是数据库设计问题(特别是规范化问题),而不是查询问题 理想情况下,描述将被提取到一些主数据表(以及必要的ID)。然后,关于要使用的描述的选择留在'SELECT'运行时。这样做的另一个好处是可以使“AS ABOVE”对订购的变化安全。
因此,假设order_ref列的每个实例都应该有不同的描述(除非'AS ABOVE'位),表格可以重构如下:
id | order_ref | price
=======================
1 | 34567 | 19.99
2 | 34567 | 13.99
和
order_ref_fk | description
==========================================
34567 | "This is the description"
此时,您正常加入描述表。显示不同的描述通常是 display 问题,无论是由输出要显示的行(而不是直接在数据库中)的任何程序处理。
如果你坚持在in-db中这样做,你可以用这种方式编写SELECT
:
SELECT Orders.id, Orders.order_ref, Orders.price,
COALESCE(Dsc.description, 'AS ABOVE')
FROM Orders
LEFT JOIN (Description
JOIN (SELECT order_ref, MIN(id) AS id
FROM Orders
GROUP BY order_ref) Ord
ON Ord.order_ref = Description.order_ref_fk) Dsc
ON Dsc.order_ref_fk = Orders.order_ref
AND Dsc.id = Orders.id
ORDER BY Orders.order_ref, Orders.id