Как я могу выполнить это обновление таблицы, используя только SQL?
Я делаю некоторые преобразования базы данных, чтобы подготовить базу данных для обновления следующей версии моего приложения. Есть один конкретный сценарий, с которым я столкнулся, что я работаю как код C # в LINQPad (LINQPad запускает преобразование), но он waaaaayyyy медленный, и я хочу попробовать и преобразовать его в прямой SQL. В противном случае, похоже, что преобразование займет около двух дней, используя код C #, и я не могу отключить приложение так долго, чтобы это произошло. В сценарии я пытаюсь обновить столбец, который раньше не существовал. Рассмотрим следующие таблицы:
Таблица J (для @maccettura)
------ | Id | ------ | 1 | ------
Таблица P
- «Недопустимое использование оператора боковой операции« ОТКРЫТЬ СИММЕТРИЧЕСКИЙ КЛЮЧ «в функции». Ошибка при открытии симметричного ключа
- SQL Server: группировать аналогичные продажи вместе
- SQL Server 2012 FileTable Медленная производительность при создании файла (интеграция Lucene.NET)
- SQL Server: выберите записи, содержащие любые HTML-объекты в столбце VARCHAR (MAX)
- SQL Join / Pivot / Unpivot = Madness
------------------------- | 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. Я попытался возиться с выбором в temp-таблицы, пытаясь сопоставить номер строки и т. Д., Но я просто недостаточно квалифицирован для SQL, чтобы заставить его работать. Я был бы признателен, если бы кто-нибудь мог указать мне в правильном направлении. Если это имеет значение, вот как выглядит форма пользовательского интерфейса:
----------------- ------------- | 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
столбцом DateAt
. В текущей версии, если пользователь добавляет дату не в порядке, кто-то переводит все данные, чтобы даты были в порядке. Как вы можете себе представить, это огромная трата времени, поэтому я хочу сделать это неуместным, что такое порядок входа, но отображать его так, как должно быть.
Единственное «отношение», которое у меня есть, это порядок столбцов Id
в таблицах P и DR . Первая строка P – это первая дата, а последняя строка P – это последняя дата. Первая строка DR для первой даты, а последняя строка DR – для последней даты.
О, и база данных – это SQL Server 2012. Заранее благодарим за любую помощь!
- Найти пространство «табулятор» в текстовом поле на SQL
- Пейджинг по группам записей вместо строк
- Есть ли способ удалить значение диапазона из таблицы разделов (sql server 2012)
- Список компонентов первичного ключа
- Дублирование записей родительских, дочерних и внуков
- SQL Server - игнорирование всегда истинного условия
- Конкатенация + разница во времени
- Согласование нечеткой логики
Это будет работать:
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
после обновления:
EDIT Похоже, что таблица P
не имеет надежных id
. Вы можете создать их с другим использованием 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
Обязательно сначала создайте резервную копию своей базы данных, но инструкция update с предложением from
должна делать то, что вам нужно:
update dr set dr.DateAt = p.DateAt from p where dr.id = p.id
Примечание:
Если у вас еще нет индекса для id
для обеих таблиц, вы, вероятно, захотите добавить его до этого. Если ваш стол большой, это займет некоторое время, если вы будете выполнять полное сканирование таблицы.