SQLite-将同一表中多个行的值插入另一个表中的一行

时间:2018-10-03 20:39:39

标签: sqlite

我有一张电话号码表(tblPhoneNumbers): ID,用户ID,电话号码

,我需要将它们移到包含以下内容的Users表(tblUsers)中: ID,电话号码1,电话号码2

假定

tblPhoneNumbers每个用户都有2行。是否可以将第一行的PhoneNumber值移动到PhoneNumber1,将第二行的PhoneNumber值移动到PhoneNumber2?

本质上,这是反向标准化,但这是我需要帮助的任务。 谢谢!

我需要使用SQLite,所以我不能使用SQLite不可用的任何语法。

2 个答案:

答案 0 :(得分:1)

您可以使用以下内容:-

-- Create a temporary swap table
CREATE TEMP TABLE IF NOT EXISTS swapPhoneNumbers (ID INTEGER PRIMARY KEY, UserID INTEGER, PhoneNumber TEXT, replacementPhoneNumber TEXT);
-- Clear the temporary swap table in case it's used more than once
DELETE FROM swapPhoneNumbers;
-- Populate the temporary swap table according to the original data
INSERT INTO swapPhoneNumbers (ID,UserID,PhoneNumber) SELECT * FROM tblPhoneNumbers;
-- Update the swap table to include the replacement phone numbers
UPDATE swapPhoneNumbers SET replacementPhoneNumber = (
    SELECT PhoneNumber FROM tblPhoneNumbers 
    WHERE swapPhoneNumbers.userID = tblPhoneNumbers.userID 
        AND swapPhoneNumbers.ID <> tblPhoneNumbers.ID
);
-- Update the original table with the new phone numbers
UPDATE tblPhoneNumbers SET PhoneNumber = (
    SELECT replacementPhoneNumber FROM swapPhoneNumbers 
    WHERE tblPhoneNumbers.ID = swapPhoneNumbers.ID
);

以下是用于测试上述内容的SQL。

-- Create Testing Table with some data
DROP TABLE IF EXISTS tblphoneNumbers;
CREATE TABLE IF NOT EXISTS tblPhoneNumbers (ID INTEGER PRIMARY KEY, userID INTEGER, PhoneNumber TEXT);
INSERT INTO tblPhoneNumbers (userID, PhoneNumber) VALUES
    (1,'0111111111'),(1,'0222222222'),(2,'0333333333'),(2,'0444444444'),(3,'0555555555'),(3,'0666666666')
;

-- Show what is in the original table
SELECT * FROM tblPhoneNumbers;

-- Create a temporary swap table
CREATE TEMP TABLE IF NOT EXISTS swapPhoneNumbers (ID INTEGER PRIMARY KEY, UserID INTEGER, PhoneNumber TEXT, replacementPhoneNumber TEXT);
-- Clear the temporary swap table in case it's used more than once
DELETE FROM swapPhoneNumbers;
-- Populate the temporary swap table according to the original data
INSERT INTO swapPhoneNumbers (ID,UserID,PhoneNumber) SELECT * FROM tblPhoneNumbers;
-- Show what is in the swap table
SELECT * FROM swapPhoneNumbers;
-- Update the swap table to include the replacement phone numbers
UPDATE swapPhoneNumbers SET replacementPhoneNumber = (
    SELECT PhoneNumber FROM tblPhoneNumbers 
    WHERE swapPhoneNumbers.userID = tblPhoneNumbers.userID 
        AND swapPhoneNumbers.ID <> tblPhoneNumbers.ID
);
-- Show what is now in the swap table
SELECT * FROM swapPhoneNumbers;
-- Update the original table with the new phone numbers
UPDATE tblPhoneNumbers SET PhoneNumber = (
    SELECT replacementPhoneNumber FROM swapPhoneNumbers 
    WHERE tblPhoneNumbers.ID = swapPhoneNumbers.ID
);
-- Show what is in the original table
SELECT * FROM tblPhoneNumbers;

这是操作的一些屏幕截图

enter image description here

enter image description here

enter image description here

enter image description here

答案 1 :(得分:1)

如果您使用的是sqlite 3.25或更高版本,则可以使用窗口函数在一条语句中完成所有操作(我假设tblPhoneNumbers中的UserID列是引用tblUsers中的ID的外键,并且给定的userid该表中已有记录;请根据需要进行调整):

WITH allnumbers AS
  (SELECT UserID
        , PhoneNumber
        , row_number() OVER (PARTITION BY UserID) AS num
   FROM tblPhoneNumbers)
UPDATE tblUsers AS t
SET PhoneNumber1 = (SELECT a.PhoneNumber
                    FROM allnumbers AS a
                    WHERE a.UserID = t.ID AND num = 1)
  , PhoneNumber2 = (SELECT a.PhoneNumber
                    FROM allnumbers AS a
                    WHERE a.UserID = t.ID AND num = 2);

(如果您的系统仅具有不支持窗口功能的较旧版本,则您始终可以download a copy of the latest version使用sqlite3 shell,而不用它提供的OS)。

(编辑:您需要在tblPhoneNumbers.UserID上建立索引以提高性能)