Как получить следующую запись в таблице SQL - PullRequest
2 голосов
/ 03 февраля 2009

У меня есть набор записей в моей таблице MS SQL. С датой в качестве первичного ключа. Но Даты только на рабочие дни, а не на продолжающиеся дни. Например:

1/3/2000 12:00:00 AM 5209.540000000 5384.660000000 5209.540000000 5375.110000000 1/4/2000 12:00:00 AM 5533.980000000 5533.980000000 5376.430000000 5491.010000000 1/5/2000 12:00:00 AM 5265.090000000 5464.350000000 5184.480000000 5357.000000000 1/6/2000 12:00:00 AM 5424.210000000 5489.860000000 5391.330000000 5421.530000000 1/7/2000 12:00:00 AM 5358.280000000 5463.250000000 5330.580000000 5414.480000000 1/10/2000 12:00:00 AM 5617.590000000 5668.280000000 5459.970000000 5518.390000000 11.01.2000 12:00:00 5513.040000000 5537.690000000 5221.280000000 5296.300000000 1/12/2000 12:00:00 AM 5267.850000000 5494.300000000 5267.850000000 5491.200000000

В этом я пытаюсь ввести новый столбец в таблицу, и значением для него должно быть значение 3-го столбца минус значение 3-го столбца предыдущего рабочего дня. Пожалуйста, помогите мне в написании такого запроса. Я нахожу это трудным, поскольку даты не заканчиваются на выходные.

Ответы [ 3 ]

2 голосов
/ 03 февраля 2009

Есть несколько способов сделать это. Вот один.

CREATE TABLE MyTable
(
    MyDate datetime NOT NULL PRIMARY KEY,
    Col2 decimal(14,4) NOT NULL,
    Col3 decimal(14,4) NOT NULL,
    Col4 decimal(14,4) NOT NULL,
    Col5 decimal(14,4) NOT NULL
)
GO

INSERT INTO MyTable
SELECT '1/3/2000 12:00:00 AM', 5209.540000000, 5384.660000000, 5209.540000000, 5375.110000000 
 UNION ALL 
SELECT '1/4/2000 12:00:00 AM', 5533.980000000, 5533.980000000, 5376.430000000, 5491.010000000
 UNION ALL 
SELECT '1/5/2000 12:00:00 AM', 5265.090000000, 5464.350000000, 5184.480000000, 5357.000000000
 UNION ALL 
SELECT '1/6/2000 12:00:00 AM', 5424.210000000, 5489.860000000, 5391.330000000, 5421.530000000 
 UNION ALL 
SELECT '1/7/2000 12:00:00 AM', 5358.280000000, 5463.250000000, 5330.580000000, 5414.480000000 
 UNION ALL 
SELECT '1/10/2000 12:00:00 AM', 5617.590000000, 5668.280000000, 5459.970000000, 5518.390000000 
 UNION ALL 
SELECT '1/11/2000 12:00:00 AM', 5513.040000000, 5537.690000000, 5221.280000000, 5296.300000000 
 UNION ALL 
SELECT '1/12/2000 12:00:00 AM', 5267.850000000, 5494.300000000, 5267.850000000, 5491.200000000
GO

CREATE VIEW MyView 
AS
SELECT T1.*,
    CalculatedColumn = Col3 - 
      (SELECT Col3 FROM MyTable Q2
       WHERE Q2.MyDate = (SELECT MAX(Q1.MyDate) 
                          FROM MyTable Q1 
                          WHERE Q1.MyDate < T1.MyDate)
    )
FROM MyTable T1
GO

SELECT * FROM MyView
GO

Результаты

MyDate                  Col2      Col3      Col4      Col5      CalculatedColumn
----------------------- --------- --------- --------- --------- ----------------
2000-01-03 00:00:00.000 5209.5400 5384.6600 5209.5400 5375.1100 NULL
2000-01-04 00:00:00.000 5533.9800 5533.9800 5376.4300 5491.0100 149.3200
2000-01-05 00:00:00.000 5265.0900 5464.3500 5184.4800 5357.0000 -69.6300
2000-01-06 00:00:00.000 5424.2100 5489.8600 5391.3300 5421.5300 25.5100
2000-01-07 00:00:00.000 5358.2800 5463.2500 5330.5800 5414.4800 -26.6100
2000-01-10 00:00:00.000 5617.5900 5668.2800 5459.9700 5518.3900 205.0300
2000-01-11 00:00:00.000 5513.0400 5537.6900 5221.2800 5296.3000 -130.5900
2000-01-12 00:00:00.000 5267.8500 5494.3000 5267.8500 5491.2000 -43.3900
1 голос
/ 03 февраля 2009

Используйте самообъединение и оператор case, который использует встроенную в SQLServers функцию даты datepart(dw,@Date).

Я чувствую себя обязанным отметить, что такое преобразование в первую очередь, вероятно, плохая идея.

1 голос
/ 03 февраля 2009

Вы должны разбить это на 2 части. Во-первых, обновляются существующие данные, а во-вторых, обеспечивается правильное добавление всех новых данных.

Для первой части рассмотрите возможность использования курсора. Вероятно, это займет некоторое время, но, по крайней мере, вы запустите его только один раз. Используйте CURSOR как цикл FOR; перебирайте каждую строку в ваших данных, игнорируя первую строку (так как вы не указали, как рассчитать значение для нового столбца, когда нет предыдущей даты). Скорее всего, вам следует отсортировать по дате по возрастанию, на всякий случай.

Когда вы выполняете итерацию, используйте переменные для хранения значений из этой строки. Во время цикла скопируйте эти переменные в предыдущие версии строки, прежде чем получите новую строку. Например, у вас есть переменная с именем «Col3», а другая с именем «lastCol3». Перед тем как перейти к следующей строке (т. Е. Курсор переместится на следующую строку), вы копируете значение col3 в lastCol3, а затем получаете новое значение для col3. Теперь у вас есть текущее и предыдущее значение для каждой строки, и вы можете вызвать 'update', чтобы обновить новый столбец.

Для получения новых данных необходимо убедиться, что указано новое значение, или, если вы хотите, чтобы SQL Server это делал, использовать хранимую процедуру, которая выбирает самую последнюю строку, col3, и использует значение для вычисления нового значения. значение перед вставкой в ​​таблицу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...