我正在进行一些数据库转换,为我的应用程序的下一个版本更新准备数据库。我遇到了一个特定的场景,我在LINQPad中运行C#代码(LINQPad正在运行转换),但是它很慢,我想尝试将其转换为直接SQL。否则看起来使用C#代码转换大约需要两天时间,并且我无法长时间禁用应用程序以实现此目的。在这种情况下,我试图更新之前不存在的列。请考虑以下表格:
表J (对于@maccettura)
------
| Id |
------
| 1 |
------
表P
-------------------------
| Id | JId | DateAt |
-------------------------
| 1 | 1 | 2017-01-01 |
| 2 | 1 | 2017-02-01 |
| 3 | 1 | 2017-03-01 |
-------------------------
表D
------------
| Id | JId |
------------
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
------------
表格DR
---------------------
| Id | DId | DateAt |
---------------------
| 1 | 1 | NULL |
| 2 | 1 | NULL |
| 3 | 2 | NULL |
| 4 | 2 | NULL |
| 5 | 3 | NULL |
| 6 | 3 | NULL |
---------------------
我想更新表 DR ,以便填写日期,数据如下所示:
-------------------------
| Id | DId | DateAt |
-------------------------
| 1 | 1 | 2017-01-01 |
| 2 | 1 | 2017-02-01 |
| 3 | 2 | 2017-01-01 |
| 4 | 2 | 2017-02-01 |
| 5 | 3 | 2017-01-01 |
| 6 | 3 | 2017-02-01 |
-------------------------
我似乎无法在SQL中表达它。我已经尝试过选择临时表,尝试按行号等进行匹配,但是我对SQL不够熟练以使其正常工作。如果有人能指出我正确的方向,我会很感激。如果它有任何区别,请参考以下UI形式:
----------------- -------------
| D.Id | D.Id | | 1 | 2 | 3 |
---------------------------- => ------------------------
| P.DateAt | DR.Id | DR.Id | | 1/1/2017 | 1 | 3 | 5 |
| P.DateAt | DR.Id | DR.Id | | 1/2/2017 | 2 | 4 | 6 |
---------------------------- ------------------------
我试图完成所有这些操作,因为在应用更新中,我按DateAt
列对 DR 行进行排序。在当前版本中,如果用户不按顺序添加日期,则有人会重新排列所有数据,因此日期是有序的。正如你可以想象的那样,这是一个浪费时间的浪费,这就是为什么我想让它与入门订单无关,而是显示它应该是什么。
唯一的关系"我有 P 和 DR 表格中Id
列的顺序。第一个 P 行是第一个日期,最后一个 P 行是最后一个日期。第一个 DR 行用于第一个日期,最后一个 DR 行用于最后一个日期。
哦,数据库是SQL Server 2012.提前感谢您的帮助!
答案 0 :(得分:1)
这将有效:
UPDATE DR
SET DR.DATEAT = P.DATEAT
FROM (SELECT ID, DId, DATEAT, ROW_NUMBER() OVER (PARTITION BY DId ORDER BY ID) RN
FROM DR) DR
JOIN P ON P.ID = DR.RN
基本上这就是说,如果它是新DId
的第一行,则使用表P
中的第一个日期,然后使用第二行到第二个日期等等。
SELECT
看到逻辑:
SELECT *
FROM (SELECT ID, DId, DATEAT, ROW_NUMBER() OVER (PARTITION BY DId ORDER BY ID) RN
FROM DR) DR
JOIN P ON P.ID = DR.RN
SELECT
结果:
DR
:
修改强>
听起来P
表没有可靠的id
s。如果需要,您可以创建另外使用ROW_NUMBER()
的那些:
SELECT *
FROM (SELECT ID, DId, DateAt, ROW_NUMBER() OVER (PARTITION BY DId ORDER BY ID) RN
FROM DR) DR
JOIN (SELECT DateAt, ROW_NUMBER() OVER (ORDER BY DateAt ASC) as ID
FROM P
) P ON P.ID = DR.RN
答案 1 :(得分:0)
请务必先备份数据库,但带有from
子句的更新语句应该可以满足您的需求:
update dr
set
dr.DateAt = p.DateAt
from
p
where
dr.id = p.id
效果说明:
如果您在两个表中都没有id
的索引,则可能需要在执行此操作之前添加一个索引。如果您的表很大,如果您正在进行全表扫描,则需要一段时间。