我有两个父/子关系表。我想用来自孩子的数据更新父母。但假设有2个孩子,我希望能够根据孩子的其他一些栏目选择使用哪个孩子进行更新。 这是我到目前为止: 家长:@test 孩子:@exdat 预期结果,更新后父母的结果应仅包含大写字母。我想用来自孩子的一些数据来更新父母,但是如果存在多个数据,我宁愿选择一个p1比p2高,p2高于p3而p3高于p4的孩子
DECLARE @test TABLE
(
id int,
val char(1)
);
DECLARE @exdat TABLE
(
id int,
dval char(1),
dimp char(2)
);
INSERT INTO @test (id,val)
SELECT 1,'a'
UNION ALL SELECT 2,'b'
UNION ALL SELECT 3,'c'
UNION ALL SELECT 4,'d'
UNION ALL SELECT 5,'e'
UNION ALL SELECT 6,'f'
UNION ALL SELECT 7,'g'
;
INSERT INTO @exdat (id,dval,dimp)
SELECT 1,'A','p1'
UNION ALL SELECT 2,'B','p3'
UNION ALL SELECT 3,'C','p1'
UNION ALL SELECT 4,'D','p2'
UNION ALL SELECT 5,'E','p2'
UNION ALL SELECT 6,'F','p3'
UNION ALL SELECT 7,'w','p2'
UNION ALL SELECT 7,'g','p3'
UNION ALL SELECT 7,'G','p1'
UNION ALL SELECT 7,'z','p4'
;
UPDATE @test SET
val = e.dval
FROM
@test t
INNER JOIN @exdat e ON t.id = e.id
;
SELECT * FROM @test;
Result:
1 A
2 B
3 C
4 D
5 E
6 F
7 w <-- problem illustrated here
这个“w”可以是任何值w,g,G,z。所以我问我如何根据其他专栏确定子选择的优先顺序?
答案 0 :(得分:3)
您想要做什么而不是连接是一个子查询。像这样:
UPDATE
a
SET
a.val = ISNULL((
SELECT TOP 1 x.dval
FROM @exdat x
WHERE x.id = a.id
ORDER BY x.magic_field -- <- here's how you specify precedence
), 'ReasonableDefault')
FROM
@test a
答案 1 :(得分:1)
尝试使用CROSS APPLY进行更新。以下示例按@extdat.dimp值排序:
DECLARE @test TABLE
(
id int,
val char(1)
);
DECLARE @exdat TABLE
(
id int,
dval char(1),
dimp char(2)
);
INSERT INTO @test (id,val)
SELECT 1,'a'
UNION ALL SELECT 2,'b'
UNION ALL SELECT 3,'c'
UNION ALL SELECT 4,'d'
UNION ALL SELECT 5,'e'
UNION ALL SELECT 6,'f'
UNION ALL SELECT 7,'g'
;
INSERT INTO @exdat (id,dval,dimp)
SELECT 1,'A','p1'
UNION ALL SELECT 2,'B','p3'
UNION ALL SELECT 3,'C','p1'
UNION ALL SELECT 4,'D','p2'
UNION ALL SELECT 5,'E','p2'
UNION ALL SELECT 6,'F','p3'
UNION ALL SELECT 7,'w','p2'
UNION ALL SELECT 7,'g','p3'
UNION ALL SELECT 7,'G','p1'
UNION ALL SELECT 7,'z','p4'
;
UPDATE @test
SET
t.val = e.dval
FROM @test as t
CROSS APPLY
(
SELECT TOP(1) * FROM @exdat as cae
WHERE t.id = cae.id
ORDER BY cae.dimp
) as e
;
SELECT * FROM @test;
如果您使用此方法,结果将如下所示:
Result:
1 A
2 B
3 C
4 D
5 E
6 F
7 G
您可以通过更改CROSS APPLY
中的顺序来修改此项答案 2 :(得分:1)
我认为使用ranking functions可以在这里得到很好的使用。
在这个样本中,我使用DENSE_RANK通过ORDER BY dimp选择最高的dimp值,然后寻找排名为1的那个。
WITH cte
AS (SELECT Dense_rank() OVER (PARTITION BY id ORDER BY dimp) AS foo,
*
FROM @exdat)
UPDATE @test
SET val = e.dval
FROM @test t
INNER JOIN cte e
ON t.id = e.id
WHERE foo = 1;
答案 3 :(得分:1)
UPDATE @test
SET t.val = e.dval
FROM @test t
JOIN @exdat e
ON t.id = e.id
JOIN
( SELECT id
, MIN(dimp) AS dimp --orders by dimp ascending
FROM @exdat
WHERE dval = UPPER(dval) --keeps only rows with capital letters in dval
GROUP BY id
) AS g
ON e.id = g.id
AND e.dimp = g.dimp