Как мне создать соединение между 2 операторами SELECT с помощью групп? - PullRequest
3 голосов
/ 02 июня 2019

У меня есть одна таблица с ежедневными данными о запасах, и я хочу обобщить ее за неделю. Ежедневный стол:

CREATE TABLE [dbo].[TempDaily] (
    [Symbol]    CHAR (10)  NOT NULL,
    [CloseDate] DATE       NOT NULL,
    [DailyHi]   FLOAT (53) NULL,
    [DailyLow]  FLOAT (53) NULL,
    [AdjClose]  FLOAT (53) NOT NULL,
    [WeekEnd]   DATE       NULL
);

Я хочу вставить сводку за неделю в таблицу за неделю:

CREATE TABLE [dbo].[Weekly] (
    [Symbol]    CHAR (10)  NOT NULL,
    [WeekEnd]   DATE       NOT NULL,
    [WeeklyHi]  FLOAT (53) NOT NULL,
    [WeeklyLow] FLOAT (53) NOT NULL,
    [AdjClose]  FLOAT (53) NULL
);

Для столбца [AdjClose] задано пустое значение, так как мой текущий обходной путь сначала вставляет остальные 4 столбца, а затем обновляет еженедельную таблицу недельным значением AdjClose из 3-й таблицы, что очень медленно.

Получить еженедельные данные в таблицу для первых 4 столбцов просто:

strSQL = "INSERT INTO Weekly (Symbol, WeekEnd, WeeklyHi, WeeklyLow) " &
    "SELECT Symbol, WeekEnd, MAX(DailyHi), MIN(DailyLow) " &
     "FROM TempDaily " &
     "GROUP BY Symbol, WeekEnd "

Получение еженедельного AdjClose не так просто, но я могу вставить данные во временную таблицу и затем обновить из нее еженедельную таблицу:

strSQL = "INSERT INTO Test (WeekEnd, AdjClose) " &
    "Select wdata.WeekEnd, MAX(wdata.AdjClose) " &
    "FROM " &
        "(Select CloseDate, WeekEnd, " &
        "FIRST_VALUE(AdjClose) OVER (PARTITION BY WeekEnd ORDER BY CloseDate                                            
         DESC ROWS UNBOUNDED PRECEDING) As AdjClose " &
         "FROM TempDaily) wdata " &
     "GROUP BY wdata.WeekEnd "

Я бы действительно предпочел вставить данные для всех 5 столбцов в таблицу Weekly одним оператором, а не прибегать к моему неуклюжему обходному пути, но я не смог выяснить, как объединить эти 2 оператора.

Данные из таблицы Daily представлены в формате (для ясности добавлены пробелы):

Symbol,    CloseDate,  DailyHi,DailyLow,AdjClose,   WeekEnd
AAPL      ,5/31/2019,   177.99,  175.00,  175.07,  6/1/2019
AAPL      ,5/30/2019,   179.23,  176.67,  178.30,  6/1/2019
AAPL      ,5/29/2019,   179.35,  176.00,  177.38,  6/1/2019
AAPL      ,5/28/2019,   180.59,  177.91,  178.23,  6/1/2019
AAPL      ,5/24/2019,   182.14,  178.62,  178.97,  5/25/2019
AAPL      ,5/23/2019,   180.54,  177.81,  179.66,  5/25/2019
AAPL      ,5/22/2019,   185.71,  182.55,  182.78,  5/25/2019
AAPL      ,5/21/2019,   188.00,  184.70,  186.60,  5/25/2019
AAPL      ,5/20/2019,   184.35,  180.28,  183.09,  5/25/2019

Таблица за неделю должна заканчиваться на:

Symbol,        WeekEnd, WeeklyHi, WeeklyLo,  AdjClose
AAPL      ,   6/1/2019,   180.59,   175.00,   175.07
AAPL      ,   5/25/2019,  188.00,   177.81,   178.97

Я конвертирую базу данных MS Access в VB.NET и подумал, что это будет довольно простой порт. Отличий намного больше, чем я ожидал. Любая помощь приветствуется.

Представленное ниже решение, которое я попробовал, но оно генерирует исключение SQLException: 'Неверный синтаксис рядом с' ('. Неверный синтаксис рядом с' wdata '. Поэтому я все еще пытаюсь выяснить это.

strSQL = "INSERT INTO Weekly (Symbol, WeekEnd, WeeklyHi, WeeklyLow, AdjClose) " &
"Select A.Symbol, A.WeekEnd, A.WeeklyHi, A.WeeklyLow, ISNULL(B.AdjClose, 0) as AdjClose " &
"FROM " &
    "(SELECT Symbol, WeekEnd, MAX(DailyHi) as WeeklyHi, MIN(DailyLow) as WeeklyLow " &
     "FROM TempDaily " &
     "GROUP BY Symbol, WeekEnd ) A " &
     "LEFT JOIN " & 
    "(Select wdata.WeekEnd, MAX(wdata.AdjClose) as AdjClose" &
    "FROM " &
        "(Select CloseDate, WeekEnd, " &
        "FIRST_VALUE(AdjClose) OVER (PARTITION BY WeekEnd ORDER BY CloseDate                                            
         DESC ROWS UNBOUNDED PRECEDING) As AdjClose " &
         "FROM TempDaily) wdata " &
     "GROUP BY wdata.WeekEnd) B ON A.WeekEnd = B.WeekEnd "

1 Ответ

0 голосов
/ 02 июня 2019

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

    strSQL = "INSERT INTO Weekly (Symbol, WeekEnd, WeeklyHi, WeeklyLow, AdjClose) " &
"Select A.Symbol, A.WeekEnd, A.WeeklyHi, A.WeeklyLow, ISNULL(B.AdjClose, 0) as AdjClose " &
"FROM " &
    "(SELECT Symbol, WeekEnd, MAX(DailyHi) as WeeklyHi, MIN(DailyLow) as WeeklyLow " &
    "FROM TempDaily " &
    "GROUP BY Symbol, WeekEnd ) A " &
    "LEFT JOIN " &
    "(Select wdata.WeekEnd, MAX(wdata.AdjClose) as AdjClose " &
    "FROM " &
        "(Select CloseDate, WeekEnd, " &
        "FIRST_VALUE(AdjClose) OVER (PARTITION BY WeekEnd ORDER BY CloseDate " &
        "DESC ROWS UNBOUNDED PRECEDING) As AdjClose " &
        "FROM TempDaily) wdata " &
     "GROUP BY wdata.WeekEnd) B ON A.WeekEnd = B.WeekEnd "
...