我有一个表,其数据如下。
说我有两个版本的项目,我需要将数据从旧版本迁移到新版本。
让我们在版本1中说tblFolders
+----+------------+--------------+--------------+
| id | FolderName | CreatedBy | ModifiedBy |
+----+------------+--------------+--------------+
| 1 | SIMPLE | 5 | 6 |
| 2 | SIMPLE1 | 8 | 1 |
+----+------------+--------------+--------------+
和另一个具有两个版本的用户名的表。
我们假设其tblUsersMapping
+----+----------------+-------------------+
| id | Version1UserID | Version2UserID |
+----+----------------+-------------------+
| 1 | 1 | 500 |
| 2 | 2 | 465 |
| 3 | 3 | 12 |
| 4 | 4 | 85 |
| 5 | 5 | 321 |
| 6 | 6 | 21 |
| 7 | 7 | 44 |
| 8 | 8 | 884 |
+----+----------------+-------------------+
现在我需要将数据从版本1传输到版本2。当我传输数据时, CreatedBy 和 Modifiedby ID应该是新版本的。
所以尽管我有以下数据
| 1 | SIMPLE | 5 | 6 |
应按以下方式转移
| 1 | SIMPLE | 321 | 21 |
为此,到目前为止,我在这两个表之间添加了一个联接,如下所示。
SELECT id,
foldername,
B.version2userid AS CreatedBy
FROM tblfolders A WITH(nolock)
LEFT JOIN tblusersmapping B WITH(nolock)
ON A.createdby = B.version1userid
这将为列 CreatedBy 提供适当的结果。
但是如何从tblUsersMapping的ModifiedBy列获取用户ID? 下面的操作将不起作用,并且两列都将为NULL。
SELECT id,
foldername,
b.version2userid AS createdby,
b.version2userid AS modifiedby
FROM tblfolders A WITH(nolock)
LEFT JOIN tblusersmapping B WITH(nolock)
ON a.createdby = b.version1userid,
a.modifiedby = b.version1userid
一种方法是我可以使用tblusersmapping表添加另一个联接。但这不是一个好主意,因为表可能具有大量数据,而另一个联接会影响查询的性能。
我的问题是如何从基于createdby和Modifyed列的映射表中获取Version1UserID和Version2UserID?
答案 0 :(得分:3)
您可以使用多项选择来帮助您。
SELECT id,
foldername,
(SELECT version2userid from tblUsersMapping where Version1UserID=tblfolders.CreatedBy) AS CreatedBy,
(SELECT version2userid from tblUsersMapping where Version1UserID=tblfolders.ModifiedBy) AS ModifiedBy
FROM tblfolders
答案 1 :(得分:2)
如果您想同时填充每一列所连接到的两列到不同的行,那么在这种情况下,您必须将同一张表连接两次,如下所示。您无法通过单个表联接来实现它。
SELECT id,
foldername,
B.version2userid AS CreatedBy
C.Version2UserID AS ModifiedBy
FROM tblfolders A WITH(nolock)
LEFT JOIN tblusersmapping B WITH(nolock)
ON A.createdby = B.version1userid
LEFT JOIN tblusersmapping C WITH(nolock)
ON A.ModifiedBy = C.version1userid
答案 2 :(得分:2)
尝试一下,它将适用于所有示例数据,
select tf.id,tf.FolderName
,oa.Version2UserID as CreatedBy
,oa1.Version2UserID as ModifiedBy
from @tblFolders tf
outer apply(select top 1 Version2UserID
from @tblUsersMapping tu
where tu.Version1UserID= tf.CreatedBy order by id desc)oa
outer apply(select top 1 Version2UserID
from @tblUsersMapping tu
where tu.Version1UserID= tf.ModifiedBy order by id desc)oa1
答案 3 :(得分:2)
您可以使用UDF
返回modifiedby
和INNER JOIN
而不是LEFT JOIN
(如果满足要求),如下所示。我认为这对表演有帮助
CREATE TABLE tblFolders (id INT, folderName VARCHAR(20), createdBy INT, modifiedBy INT)
INSERT INTO tblFolders VALUES
(1,'SIMPLE', 5,6),
(2,'SIMPLE1', 8,1)
CREATE TABLE tblUsersMapping(id INT, Version1UserID INT, Version2UserID INT)
INSERT INTO tblUsersMapping VALUES
(1,1,500),
(2,2,465),
(3,3,12),
(4,4,85),
(5,5,321),
(6,6,21),
(7,7,44),
(8,8,884)
SELECT a.id,
a.foldername,
b.version2userid AS createdby,
dbo.FNAReturnModifiedBy(a.modifiedBy) AS modifiedby
FROM tblfolders A WITH(nolock)
INNER JOIN tblusersmapping B WITH(nolock) ON a.createdby = b.version1userid
--Function
IF OBJECT_ID(N'dbo.FNAReturnModifiedBy', N'FN') IS NOT NULL
DROP FUNCTION dbo.FNAReturnModifiedBy
GO
CREATE FUNCTION dbo.FNAReturnModifiedBy(@updated_by INT)
RETURNS INT AS
BEGIN
DECLARE @updateUserID INT
SELECT @updateUserID = Version2UserID
FROM tblusersmapping WHERE Version1UserID = @updated_by
RETURN @updateUserID
END
输出:
id foldername createdby modifiedby
1 SIMPLE 321 21
2 SIMPLE1 884 500
答案 4 :(得分:2)
注意:
我不知道如何查找查询性能。我只为您的预期输出而写。
我正在使用SQL Server 2012。
我没有使用多个Join。
查询执行了JOIN, GROUP BY, ROW_NUMBER (), CASE
,而不是两个LEFT JOIN
输入:
create table ##ver (id int, FolderName varchar (10), CreatedBy int, ModifiedBy int)
insert into ##ver values
(1,'SIMPLE',5,6)
,(2,'SIMPLE1',8,1)
,(3,'File',7, 5)
select * from ##ver
create table ##veruser (id int, Version1UserID int, Version2UserID int)
insert into ##veruser values
(1 , 1 , 500)
,(2 , 2 , 465)
,(3 , 3 , 12 )
,(4 , 4 , 85 )
,(5 , 5 , 321)
,(6 , 6 , 21 )
,(7 , 7 , 44 )
,(8 , 8 , 884)
select * from ##veruser
查询:
select
id, FolderName
, max (case when rn = 1 then Version2UserID end) Version1UserID
, max (case when rn = 2 then Version2UserID end) Version2UserID
from (
select
v.id, v.FolderName, u.Version1UserID, u.Version2UserID
, ROW_NUMBER () over
(partition by v.id order by v.id, v.CreatedBy,
case
when v.CreatedBy > v.ModifiedBy then u.Version1UserID
end desc
) rn
, v.CreatedBy, v.ModifiedBy
from ##ver v
join ##veruser u
on u.Version1UserID in (v.CreatedBy, v.ModifiedBy)
) a
group by id, FolderName
order by id
更新1:
查询:
加入表格。
行号,在()上方,
按ID分区。
按文件ID(v.id)排序,创建者ID递增,如果创建者ID更大 比修改过的ID少,然后创建者ID降序。 (由于第二步,必须重新排序)
取决于'rn'值,行将转移到列
(您可以在here上找到很多示例)
输出:
id FolderName Version1UserID Version2UserID
1 SIMPLE 321 21
2 SIMPLE1 884 500
3 File 44 321
答案 5 :(得分:1)
尝试这个。
Select a.id,folderName,b.Version2UserId as createdby,c.Version2UserId as modifiedby
from tblFolders as a WITH(nolock)
inner join tblUsersMapping as b WITH(nolock) on a.createdby =b .Version1UserID
inner join tblUsersMapping as c WITH(nolock) on a.modifiedBy =c .Version1UserID