我有一张电话号码表(tblPhoneNumbers): ID,用户ID,电话号码
,我需要将它们移到包含以下内容的Users表(tblUsers)中: ID,电话号码1,电话号码2
假定tblPhoneNumbers每个用户都有2行。是否可以将第一行的PhoneNumber值移动到PhoneNumber1,将第二行的PhoneNumber值移动到PhoneNumber2?
本质上,这是反向标准化,但这是我需要帮助的任务。 谢谢!
我需要使用SQLite,所以我不能使用SQLite不可用的任何语法。
答案 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;
这是操作的一些屏幕截图
答案 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
上建立索引以提高性能)