Получить значение из предыдущих данных строки для следующих данных по датам - PullRequest
1 голос
/ 23 сентября 2019

У меня есть транзакции таблицы 2, скажем, таблицы A и B, в некоторых случаях мне нужно перенести данные строки из таблицы B в A как новую таблицу с несколькими условиями:

  • Цена запередаваемые данные будут следовать из предыдущих данных
  • Эта же дата не будет преобразована в результаты
  • Если нет предыдущих данных, они не будут обработаны в результаты

Например:

    -----------Table A-------------      ----------Table B---------- 
    product |   Date      | Price |      | Product  |     Date     |  
       A    | 2019-01-01  |  10   |      |    A     |  2018-11-05  |
       A    | 2019-01-15  |  15   |      |    A     |  2019-01-10  |
       A    | 2019-01-25  |  20   |      |    A     |  2019-01-12  |
       A    | 2019-05-01  |  25   |      |    A     |  2019-01-27  |
       A    | 2019-07-02  |  30   |      |    B     |  2019-02-10  |
       B    | 2019-02-05  |  40   |      |    B     |  2019-04-22  |
       B    | 2019-04-22  |  50   |      |    B     |  2019-05-13  |
       B    | 2019-05-12  |  40   |

Результат:

         -----------Table C-------------      
        product |   Date      | Price |      
           A    | 2019-01-01  |  10   |      
           A    | 2019-01-10  |  10   |  *The prices follow the data in the previous date (2019-01-01)
           A    | 2019-01-12  |  10   |  *The prices follow the data in the previous date (2019-01-01)
           A    | 2019-01-15  |  15   |      
           A    | 2019-01-25  |  20   |      
           A    | 2019-01-27  |  20   |  *The prices follow the data in the previous date (2019-01-25)
           A    | 2019-05-01  |  25   |      
           A    | 2019-07-02  |  30   |      
           B    | 2019-02-05  |  40   |
           B    | 2019-02-10  |  40   |  *The prices follow the data in the previous date (2019-02-05)
           B    | 2019-04-22  |  50   |      
           B    | 2019-05-12  |  40   |
           B    | 2019-05-13  |  40   |  *The prices follow the data in the previous date (2019-05-12)

ПРИМЕЧАНИЕ:

  • Для продукт A в таблице B в 2018-11-05 не обрабатывается в результатах, так как в этой таблице нет данных до этой даты для этого продукта.
  • Для продукт B в таблице B на 2019-04-22 не преобразован в результаты, поскольку дата и продукт в таблицах A и B совпадают (данные уже находятся в таблице A)

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

Ответы [ 3 ]

3 голосов
/ 23 сентября 2019

Один способ - использовать group by в cte, а затем union:

WITH cte AS(
SELECT b.product,
        b.[Date],
        MAX(a.[Date]) AS [DateValue]
FROM TableA AS a
INNER JOIN TableB AS b ON a.product = b.product
WHERE a.[Date] <= b.[Date]
GROUP BY b.product, b.[Date]
)
SELECT *
FROM dbo.TableA AS a
UNION
SELECT b.product,
        b.[Date],
        a.Price
FROM cte AS c
INNER JOIN dbo.TableB AS b ON b.product = c.product AND b.[Date] = c.[Date]
INNER JOIN dbo.TableA AS a ON a.product = c.product AND a.[Date] = c.[DateValue]
ORDER BY product, [Date]
3 голосов
/ 23 сентября 2019

Один метод использует union all и cross apply:

select ab.product, ab.date, p.price
from ((select a.product, a.date
       from a
      ) union   -- intentional to remove duplicates
      (select b.product b.date
       from b
      )
     ) ab cross apply
     (select top (1) a.price
      from a
      where a.product = ab.product and a.date <= ab.date
      order by ab.date desc
     ) p;

Обратите внимание, что cross apply удалит строки из b, которые не имеют цены.

Если поддержка SQLопция ignore nulls в last_value() или lag(), это было бы более уместно с full join:

select coalesce(a.product, b.product) as product, 
       coalesce(a.date, b.date) as date,
       coalesce(a.price,
                lag(ignore nulls a.price) over (partition by coalesce(a.product, b.product) order by coalesce(a.date, b.date)) as price
from a full join
     b
     on a.product = b.product and a.date = b.date;

Увы, SQL Server (в настоящее время) не поддерживает это.Вы можете сделать это с небольшими усилиями и дополнительными подзапросами.

1 голос
/ 23 сентября 2019

SQL MERGE - очень мощный инструмент для выполнения операции "CRUD" на основе некоторых условий ...

Пожалуйста, перейдите по ссылке для получения более подробной информации об этой функции.

http://www.sqlservertutorial.net/sql-server-basics/sql-server-merge/

https://www.essentialsql.com/introduction-merge-statement/

Пожалуйста, не стесняйтесь спрашивать, если у вас есть какие-либо сомнения.

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