我在SQL Server 2008 R2中进行数据迁移。我是一个SQL-Server noob,但我非常了解Ingres和MySql。
我需要将两个新字段的“默认值”设置为另一个表中的“当前值”。这是我第一次天真的尝试(我如何在Ingres中做到这一点)。
update rk_risk
set n_target_probability_ID = a.n_probability_ID
, n_target_consequence_ID = a.n_consequence_ID
from rk_assess a
WHERE a.n_assess_id = (
SELECT MAX(n_assess_id)
FROM rk_assess a2
WHERE a2.n_risk_id = a.n_risk_id
);
上述查询在续集中执行时没有错误,但它设置 ALL n_target_probability_ID& n_target_consequence_ID指向相同值 ... OUTRIGHT最后一次评估的结果(与“此次风险的最后评估”相对应)。
rk_assess
表包含rk_risk
的评估记录的完整历史记录,我的任务是“默认”新的目标概率&风险表的后果列,来自“当前”(即最后一个)评估记录的值。 rk_assess.n_assess_id
列是一个自动递增的标识符(一旦设置为不可变),因此max-id应始终是最后输入的记录。
我在google和SO上都进行了一些搜索,尝试了一些不同版本的查询,但我仍然陷入困境。这里有几个史诗般的失败,有参考。
update rk_risk
set n_target_probability_ID = (select a.n_probability_ID from rk_assess a where a.n_assess_id = (select max(n_assess_id) from rk_assess a2 where a2.n_risk_id = a.n_risk_id) as ca)
, n_target_consequence_ID = (select a.n_consequence_ID from rk_assess a where a.n_assess_id = (select max(n_assess_id) from rk_assess a2 where a2.n_risk_id = a.n_risk_id) as ca)
;
http://stackoverflow.com/questions/6256844/sql-server-update-from-select
update r
set r.n_target_probability_ID = ca.n_probability_ID
, r.n_target_consequence_ID = ca.n_consequence_ID
from rk_risk r
join rk_assess a
on a.n_risk_id = r.n_risk_id
select r.n_risk_id
, r.n_target_probability_ID, r.n_target_consequence_ID
, ca.n_probability_ID, ca.n_consequence_ID
from rk_risk r
join rk_assess a
on a.n_risk_id = r.n_risk_id
http://stackoverflow.com/questions/4024489/sql-server-max-statement-returns-multiple-results
UPDATE rk_risk
SET n_target_probability_ID = ca.n_probability_ID
, n_target_consequence_ID = ca.n_consequence_ID
FROM ( rk_assess a
INNER JOIN (
SELECT MAX(a2.n_assess_id)
FROM rk_assess a2
WHERE a2.n_risk_id = a.n_risk_id
) ca -- current assessment
任何指针都将非常感激。提前谢谢大家,甚至读到这一点。
干杯。基思。
答案 0 :(得分:6)
这个怎么样:
update rk_risk
set n_target_probability_ID = a.n_probability_ID
, n_target_consequence_ID = a.n_consequence_ID
from rk_assess a
JOIN (
SELECT n_risk_id, MAX(n_assess_id) max_n_assess_id
FROM rk_assess
GROUP BY n_risk_id
) b
ON a.n_risk_id = b.n_risk_id AND a.n_assess_id = b.max_n_assess_id
WHERE a.n_risk_id = rk_risk.n_risk_id
答案 1 :(得分:3)
如果您使用sql 2005或更高版本,除了Jerad的答案之外,您还可以使用row_number函数
With b
(
SELECT n_risk_id,
n_assess_id,
n_probability_ID,
n_consequence_ID,
row_number() over (partition by n_risk_id order by n_assess_id desc) row
FROM rk_assess
)
update rk_risk
set n_target_probability_ID = b.n_probability_ID
, n_target_consequence_ID = b.n_consequence_ID
from b
WHERE a.n_risk_id = rk_risk.n_assess_id
and row =1
或CROSS JOIN
update rk_risk
set n_target_probability_ID = b.n_probability_ID
, n_target_consequence_ID = b.n_consequence_ID
from rh_risk r
CROSS JOIN
(
SELECT TOP 1
n_risk_id,
n_assess_id,
n_probability_ID,
n_consequence_ID
FROM rk_assess
order by n_assess_id desc
WHERE a.n_risk_id = r.n_assess_id) b
答案 2 :(得分:2)
我试过这个,看起来好像有效:
update rk_risk
set n_target_probability_ID = a.n_probability_ID,
n_target_consequence_ID = a.n_consequence_ID
from rk_assess a, rk_risk r
WHERE a.n_risk_id = r.n_risk_id
and a.n_assess_id in (select MAX(n_assess_id) from rk_assess group by n_risk_id)
答案 3 :(得分:1)
我今天从另一个关于SO的问题中发现了这一点。 UPDATE-FROM
构造不是标准SQL,MySQL的非标准版本与Postgres的非标准版本不同。从这里的问题来看,看起来SQL Server遵循Postgres。
Jerad在他的编辑中指出,问题在于更新的表与子查询中的表之间没有链接。 MySQL似乎在这里创建了一些隐式连接(在列名上?在另一个SO示例中,它是通过将同一个表的两个副本视为相同而不是单独的)。
我不知道SQL Server是否允许在子查询中进行窗口化,但如果确实如此,我认为你想要
UPDATE rk_risk
set n_target_probability_ID = a.n_probability_ID
, n_target_consequence_ID = a.n_consequence_ID
from
( SELECT * FROM
( SELECT n_risk_id, n_probability_ID, n_consequence_ID,
row_number() OVER (PARTITION BY n_risk_id ORDER BY n_assess_ID DESC) AS rn
FROM rk_assess)
WHERE rn = 1) AS a
WHERE a.n_risk_id=rk_risk.n_risk_id;