2011-05-14 40 views
2

下载表格:更新值

id (primary key) 
user_id 
item_id 
created_at 
updated_at 

的USER_ID和ITEM_ID在这种情况下都是不正确,但是,他们妥善储存在用户和项目表,分别为(IMPORT_ID在每个表中)。这里就是我想要的脚本:

downloads.each do |download| 
    user = User.find_by_import_id(download.user_id) 
    item = item.find_by_import_id(download.item_id) 

    if user && item 
    download.update_attributes(:user_id => user.id, :item.id => item.id) 
    end 
end 

所以,

  1. 查找基于 各自的“IMPORT_ID”的用户和项目。然后
  2. 更新的下载记录

这些值这个一吨的行永远需要。无论如何要在SQL中做到这一点?

回答

2

如果我理解正确,只需在SELECT语句中添加两个子查询来查找正确的ID。例如:

SELECT id, 
    (SELECT correct_id FROM User WHERE import_id=user_id) AS UserID, 
    (SELECT correct_id FROM Item WHERE import_id=item_id) AS ItemID, 
    created_at, 
    updated_at 
FROM Downloads 

这将你的不正确翻译user_ids您要来自用户表的任何标识,它会做同样的为您ITEM_IDS。来自SQL的信息现在是正确的。

但是,如果你想更新用正确的信息的表,你可以写这就像这样:

UPDATE Downloads 
SET user_id = User.user_id, 
    item_id = Item.item_id 
FROM Downloads 
INNER JOIN User ON Downloads.user_id = User.import_id 
INNER JOIN Item ON Downloads.item_id = Item.import_id 
WHERE ... 

确保装上去在WHERE子句中,所以你不更新每个记录在下载表中(除非这是计划)。我重写了上面的语句,因为原始版本每行有两个SELECT语句,这有点激烈。

编辑: 由于这是PostgreSQL的,你不能在UPDATEFROM部分都具有表名。相反,FROM部分中的表连接到正在更新的表。下面是从PostgreSQL的网站关于这个报价:

When a FROM clause is present, what essentially happens is that the target table is joined to the tables mentioned in the fromlist, and each output row of the join represents an update operation for the target table. When using FROM you should ensure that the join produces at most one output row for each row to be modified. In other words, a target row shouldn't join to more than one row from the other table(s). If it does, then only one of the join rows will be used to update the target row, but which one will be used is not readily predictable.

http://www.postgresql.org/docs/8.1/static/sql-update.html

考虑到这一点,这里是我认为应该工作的例子(不能测试它,不好意思):

UPDATE Downloads 
SET user_id = User.user_id, 
    item_id = Item.item_id 
FROM User, Item 
WHERE Downloads.user_id = User.import_id AND 
     Downloads.item_id = Item.import_id 

那是基本的想法。不要忘记,您仍然需要为WHERE部分添加额外条件来限制更新的行。

+0

谢谢!我需要用正确的值更新下载表。 UPDATE文件在哪里? (是的,我用SQL很糟糕) – jmccartie 2011-05-14 16:17:51

+0

@jmccartie - 你去了。如果你只是想要正确的数据,第一个SQL语句就可以工作。如果你想更新数据,第二条语句将完成这项工作。如果你想做这两个,更新数据(第二条语句),然后只需使用简单的SELECT语句从Downloads表中获取数据。 – IAmTimCorey 2011-05-14 16:28:26

+0

嗯。我得到一个新的查询错误:错误:错误:表名“下载”指定多次。有任何想法吗? – jmccartie 2011-05-15 00:07:03

1

我完全猜测你的问题,但你有一种查询表,将匹配一个导入user_id与真实 user_id,和类似的项目。即假设你的代码行:

User.find_by_import_id(download.user_id) 

访问数据库做查询。 import_users/import_items表只是我给查找表执行此操作的名称。

UPDATE downloads 
SET downloads.user_id = users.user_id 
, downloads.item_id = items.items_id 
FROM downloads 
INNER JOIN import_users ON downloads.user_id = import_users.import_user_id 
INNER JOIN import_items ON downloads.item_id = import_items.import_item_id 

无论哪种方式(查找在DB,或者它从代码中获得),岂不是更容易在首位插入正确的信息?这意味着你的桌子上不会有任何FK,因为有时他们指向一个桌子,而其他人则指向另一个桌子。似乎有点奇怪。

+0

嗯。我得到一个新的查询错误:错误:错误:表名“下载”指定多次。有任何想法吗? – jmccartie 2011-05-15 00:07:45