Обновить значение столбца на основе значения строки в той же строке, строка за строкой - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть таблица с memberID и Date, например:

MEM_ID          DATE        ttl_sales
-------------------------------------
19960124000007  2020-01-19  NULL
19960131001079  2020-01-20  NULL
19960203001249  2020-01-07  NULL
19960205000213  2020-01-14  NULL

Мне нужно обновить ttl_sales с sales_table, с условием использования MEM_ID с того же Строка и транзакции, которые произошли до DATE из той же строки.

Мне может понадобиться использовать аналогичную функцию, но с более сложными условиями (перед тем, как указать ДАТУ плюс в некоторых магазинах, с некоторыми продуктами и т.д. c .) в будущем, поэтому приветствуются как ключевые слова, так и решения.

Я использую SQL Сервер.

Спасибо.

Ответы [ 3 ]

1 голос
/ 13 апреля 2020

Самый простой способ - это координировать подзапрос, который суммирует строки в продажах на основе членов mem_id:

UPDATE members
SET ttl_sales = (
  SELECT sum(s.amount) 
  FROM sales s 
  WHERE s.sale_date < members.[date] and s.mem_id = members.mem_id
)

Я предположил, что ttl_sales - это общая сумма продаж. Если это число, используйте COUNT(*) вместо SUM(amount)

. Вы можете добавить дополнительные пункты в ГДЕ, чтобы удовлетворить ваши требования к продуктам, магазинам и т. Д. c

0 голосов
/ 13 апреля 2020

Вы также можете использовать общее табличное выражение, содержащее подзапрос с агрегацией INNER JOIN и SUM:

WITH s AS
(
 SELECT s.Mem_ID AS Mem_ID_s, 
        SUM( COALESCE(s.ttl_sales,0) ) AS ttl_sales_s
   FROM sales s
   JOIN members m 
     ON m.Mem_ID = s.Mem_ID
  WHERE s.Date < m.Date
  GROUP BY s.Mem_ID
)
UPDATE m
   SET m.ttl_sales = s.ttl_sales_s
  FROM members as m
  INNER JOIN s 
     ON m.Mem_ID = s.Mem_ID_s;

Также обратите внимание, что использование функции COALESCE() важно для случаев значений NULL для столбца ttl_sales.

Демонстрация

0 голосов
/ 13 апреля 2020

На SQL сервере вы можете использовать обновляемые CTE и оконные функции. Например, если бы вы хотели накопительное число, вы бы использовали row_number():

with toupdate as (
      select t.*,
             row_number() over (partition by memberId order by date) as seqnum
      from t
     )
update toupdate
     set ttl_sales = seqnum;

Оконные функции очень гибкие, поэтому они, вероятно, могут делать то, что вы хотите.

...