обновлять столбец в таблице только в том случае, если после обновления он не будет отрицательным и идентифицировать все обновленные строки - PullRequest
1 голос
/ 23 февраля 2010

Мне нужна помощь с запросом SQL. Вот что мне нужно сделать. Я потерял несколько аспектов, как указано ниже.

У меня есть четыре соответствующие таблицы:

В таблице A указана цена за единицу для всех ресурсов. Я могу посмотреть цену, используя идентификатор ресурса.

Таблица B содержит средства, доступные для данного пользователя.

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

В таблице D указано количество единиц, когда-либо созданных любым пользователем (может быть идентифицировано по идентификатору пользователя и идентификатору ресурса)

Сказав это, мне нужно запускать пакетное задание по ночам для выполнения следующих действий:

а. для всех пользователей определите, есть ли у них средства, необходимые для производства количества ресурсов, указанного в таблице C, и вычтите средства, если они имеются, из таблицы B (расчет стоимости с использованием таблицы A).

б. запустите процесс для создания ресурсов и после завершения производства ресурсов обновите таблицу D, используя значения из таблицы C после завершения продукта ресурса.

Я полагал, что вторую часть можно выполнить с помощью ОБНОВЛЕНИЯ с подзапросом. Тем не менее, я не уверен, как я должен делать часть а. Я могу думать только об использовании курсора для извлечения каждой строки, изучения и обновления. Есть ли один SQL-оператор, который поможет мне избежать обработки каждой строки вручную? Кроме того, если какие-либо строки не были обновлены, часть b. SQL не должен создавать ресурсы для этого пользователя.

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

Пожалуйста, дайте мне знать любые идеи и мысли.

Спасибо! - Азим

Ответы [ 2 ]

2 голосов
/ 23 февраля 2010

Без схемы сложно думать об этом, но, в принципе, вы должны сделать что-то вроде этого:

 update B b
   set amount = amount - *subquery*
   where (amount - *subquery*) > 0

является подзапросом суммы денег, потраченной этим пользователем.

 select sum(a.priceperunit * c.units)
 from C c join A a on (a.productid = c.productid)
 where c.userid = b.userid

Редактировать : Вы должны поместить части a и b в транзакцию.

0 голосов
/ 24 февраля 2010

ОК, я сделал некоторые предположения о структуре здесь (и вы хотели бы, чтобы все это было в одной транзакции)

DECLARE @outputTable (userid int)

UPDATE b
    SET amount = amount - newcharges
    OUTPUT inserted.userid INTO @outputTable
FROM tableb b
join 
    (SELECT c.userid, sum (a.amount) AS newcharges FROM tablea a
    JOIN tablec c 
        ON a.productid =c.productid
    WHERE c.date = getdate()
    GROUP BY c.userid) a1
        ON b.userid = a1.userid
WHERE b.amount >= newcharges

UPDATE d
SET units = units + c.units
FROM tabled d
JOIN tablec c ON c.unitid = d.unitid
JOIN @userid u ON c.userid = u.userid
where c.date = getdate()

Производная таблица будет заменена тем запросом, который вам понадобится для суммирования сборов, которые еще не были вычтены из таблицы:

    (SELECT c.userid, sum (a.amount) AS newcharges FROM tablea a
    JOIN tablec c 
        ON a.productid =c.productid
    WHERE c.date = getdate()
    GROUP BY c.userid) a1

На самом деле вы также можете подумать, что делать, если сумма переведет пользователя в отрицательный статус. Как вы будете получать эти данные позже, когда у него будет больше денег, или если запись из c будет помечена как не отправленная или удаленная полностью или как? Лично я думаю, что жизнеспособной альтернативой было бы проверить сумму, доступную на момент вставки записи в c, и не вставлять ее, если нет свободных денег. Это будет полезно для пользователя, который не будет обрабатывать его во время работы с данными.

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