2012-08-08 48 views
2

我已经搜查,发现的例子负载,但我仍然在努力使这项工作。更新列在同一个表

我下表具有SQLite中:

SELECT * FROM TableA; 

ID|USER|NAME|PARENT 
1|User1|SomeName|-1 
2|User1|SomeOtherName|1 
3|User2|SomeName|-1 
4|User2|SomeOtherName|-1 

父ID为2的SomeOtherName NAME是ID 1 - 这是正确的。

为ID 4 SomeOtherName的名称PARENT是ID -1 - 这是不正确。它应该是ID 3.

我有一个像很多不正确的记录(所有SomeOtherName的相同名称和-1的父母)。

是关系在一起列是USER。

我需要更新所有正确的父ID不正确的记录。

我曾尝试以下无济于事:

DROP TABLE orphans; 

CREATE TEMP TABLE orphans as 
    SELECT TableA.id, TableA.user, TableA.name FROM TableA WHERE TableA.name = 'SomeOtherName' AND TableA.parent = -1; 

UPDATE TableA 
SET parent = ( SELECT TableA.id 
         FROM TableA 
         INNER JOIN orphans 
         ON TableA.name = 'SomeName' AND orphans.user = TableA.user 
       ) 
WHERE TableA.user IN ( SELECT TableA.user 
           FROM TableA WHERE TableA.name = 'SomeOtherName' AND TableA.parent = -1) 
; 

我似乎无法得到它的权利。任何帮助将不胜感激。

回答

1

据我所知,有源码在UPDATE声明复杂的查询非常有限能力。你不能使用多个表,并且我还没有找到一种方法来引用子查询中当前行的值。

相反,我想出了这一点:

SELECT id, user, name, 
    CASE name = 'SomeOtherName' AND parent = -1 
    WHEN 1 THEN (
    SELECT MAX(id) 
    FROM TableA A2 
    WHERE A1.user = A2.user 
    AND A2.name != 'SomeOtherName' 
) ELSE parent END AS parent 
FROM TableA A1; 

应该是你想要的数据,对不对?您可以将其写入临时表,然后将数据反馈回原始表。如果您有唯一的密钥,则可以使用REPLACE来完成此反馈,如果不是,则使用DETELTE,然后使用INSERT。我创建了an example of the latter on sqlfiddle

+0

非常感谢您的帮助,这非常有帮助。在我的实时系统上使用它时唯一需要对查询进行的更改是在tmp表的末尾命名列parent1,然后将parent1作为父项插入到TableA中。可以在http://sqlfiddle.com/#!7/1a5ba/9上看到更改 – GMWebs 2012-08-10 13:44:12

0

当然后期的答复,但我相信这可以在没有临时表来完成。只需以适当的方式使用选择。 下面的代码适用于我的类似表格:

UPDATE TableA SET PARENT = (
      SELECT ID 
      FROM TableA AS T 
      WHERE T.NAME = 'SomeName' AND T.USER = TableA.USER 
     ) 
WHERE ID IN (
      SELECT ID 
      FROM TableA 
      WHERE TableA.NAME = 'SomeOtherName' AND TableA.PARENT = -1 
      ); 
+0

您是否使用sqlite执行此操作?它似乎不喜欢“AS T” – marchaos 2016-02-09 09:51:02

+0

是的,我使用SQLite 3.5.1,这工作得很好。 对不起,没有立即注意到你的问题。 – hypers 2016-02-26 09:01:39