在 SQL Server 2012 上,我有一个用于将现有数据与新数据合并的中间/暂存表,我想在其中为新创建的行插入数字 ID:
ID NaturalID Comment
1 franknfurther03071972 blahblah
2 chrisrock12081980 nonsense
null clairecampbell24121990 merry christmas
3 walterhermes22032001 young guy
4 tanjaolsen16051996 nice
null timharris20041999 came late
Run Code Online (Sandbox Code Playgroud)
带有“空”ID 的行是新的,编号的 ID 是那些已经存在于主目标表中的行。NaturalID 可以唯一标识一个条目(实际上是多列)。我想在当前最大 ID 之后将“空”ID 设置为增量值,此处为:5 和 6,在找到更多空 ID 时增加。
目前,我使用游标遍历 ID 为 null 的行并使用值更新每个 ID,但由于它确实是一个非常大的表,因此需要几天时间。
我尝试使用 row_number() 进行更新,但它给了我一个错误“窗口函数只能出现在 SELECT 或 ORDER BY 子句中。”:
update StagingTable set ID=ROW_NUMBER() over (order by NaturalId)
from StagingTable where id is null -- fails
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
如果写入查询的某些行未通过唯一约束,那么只会拒绝这些写入,还是整个查询都会失败?
假设我有这个查询:
SELECT EMP_ID,LAST_NAME FROM EMPLOYEES
WHERE POSITIONID IN (1,3) ORDER BY POSITIONID,LAST_NAME;
Run Code Online (Sandbox Code Playgroud)
现在如果我只想显示 50 到 60 之间的前十行,我能想到的唯一方法是首先使用 ROWNUM 伪列运行上面的查询,然后从这个查询的结果中进行选择。像这样的东西:
SELECT EMP_ID,LAST_NAME FROM
(SELECT ROWNUM RNUM,EMP_ID,LAST_NAME FROM
(SELECT EMP_ID,LAST_NAME FROM EMPLOYEES
WHERE POSITIONID IN (1,3) ORDER BY POSITIONID,LAST_NAME))
WHERE RNUM BETWEEN 50 AND 60;
Run Code Online (Sandbox Code Playgroud)
但是这样,我最终会首先获取职位为 1 或 3 的所有员工,然后提取其中的 10 行。我觉得这有点低效。有没有办法在不先进行全面扫描的情况下实现这一目标?
在 PostgreSQL 11 中,以下表达式
UPDATE test_table SET ("column_a","column_b") = ('value-a','value-b') WHERE "column_a" = 'value-c'
Run Code Online (Sandbox Code Playgroud)
被接受并执行更新。
但是对于单个列/值,例如
UPDATE test_table SET ("column_a") = ('value-a') WHERE "column_a" = 'value-c'
Run Code Online (Sandbox Code Playgroud)
它给出了一个错误。ROW必须提供,例如
UPDATE test_table SET ("column_a") = ROW ('value-a') WHERE "column_a" = 'value-c'
Run Code Online (Sandbox Code Playgroud)
有没有解释为什么选择这种行为?如果ROW缺少,是否有歧义?
row ×4
sql-server ×2
constraint ×1
identity ×1
optimization ×1
oracle ×1
oracle-11g ×1
postgresql ×1
syntax ×1
update ×1