Обновление SQL Server на основе уникальной строки с использованием цикла WHILE

#sql #sql-server

#sql #sql-сервер

Вопрос:

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

Есть ли способ разделить на SET @aremployee основе employeeidno?

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

 DECLARE @cnt INT = 0;
DECLARE @aremployee FLOAT = 0;
WHILE @cnt <= (SELECT TOP 1 RIGHT(accountcode,2) FROM accounting_tblearningsamendmentaccount_db WHERE LEFT(accountcode,2) = '02' AND approvedby IS NOT NULL ORDER BY accountcode DESC)
BEGIN
   SET @cnt = @cnt   1;
    UPDATE accounting_tblpayroll_db
    SET @aremployee = @aremployee   x.aremployee,
        accounting_tblpayroll_db.aremployee = @aremployee
    FROM (SELECT 
        MAX(RTRIM(LTRIM(employeeidno))) AS 'employeeidno', 
        SUM(debit) AS 'aremployee', 
        MAX(accountcode) as 'accountcode',
        MAX(RTRIM(LTRIM(referenceno))) AS 'referenceno', 
        MAX(RTRIM(LTRIM(particulars))) AS 'particulars', 
        MAX(RTRIM(LTRIM(postedby))) AS 'postedby', 
        MAX(RTRIM(LTRIM(approvedby))) AS 'approvedby', 
        MAX(RTRIM(LTRIM(notedby))) AS 'notedby' 
        FROM accounting_tblearningsamendment_db WHERE LEFT(accountcode,2) = LEFT('02000',2) 
        AND accountcode != '02001' AND accountcode != '02002'
        AND payrolldue is null AND datedue BETWEEN '2020-10-06' AND '2020-10-20'
        AND accountcode = CONCAT('020', CONCAT(CASE WHEN @cnt < 10 THEN '0' ELSE '' END , @cnt))
        GROUP BY employeeidno) AS x
    WHERE x.employeeidno = accounting_tblpayroll_db.employeeidno
        AND x.aremployee < 
        (((accounting_tblpayroll_db.cutoffpay   accounting_tblpayroll_db.leave   accounting_tblpayroll_db.nightdifferential   accounting_tblpayroll_db.regularholiday   accounting_tblpayroll_db.specialholiday   accounting_tblpayroll_db.additionalincome   accounting_tblpayroll_db.overtime
        
          accounting_tblpayroll_db.apemployee   accounting_tblpayroll_db.thmonth   accounting_tblpayroll_db.christmasbonus   accounting_tblpayroll_db.administrativeallowance   accounting_tblpayroll_db.supervisoryallowance
       accounting_tblpayroll_db.hazardallowance   accounting_tblpayroll_db.shortageallowance   accounting_tblpayroll_db.licenseallowance   accounting_tblpayroll_db.transportationallowance   loyaltyincentiveallowance - '1000.00'
        )
        - (accounting_tblpayroll_db.sss_ee   accounting_tblpayroll_db.med_ee   accounting_tblpayroll_db.pagibig_ee   accounting_tblpayroll_db.late   accounting_tblpayroll_db.undertime)))
        AND accounting_tblpayroll_db.datefrom = '2020-10-06' 
        AND accounting_tblpayroll_db.dateto = '2020-10-20';
    END;
  

Заранее благодарю вас.

Редактировать:

Это упрощенная версия:

 DROP TABLE #temtable1;
DROP TABLE #temtable2;

CREATE TABLE #temtable1
(
    referenceno int,
    employeeid varchar(10),
    ccode varchar(10),
    amount float(10)
);

INSERT INTO #temtable1
(referenceno,employeeid,ccode,amount)
VALUES('1001','2001','3001','11000.00');
INSERT INTO #temtable1
(referenceno,employeeid,ccode,amount)
VALUES('1003','2002','3002','11000.00');
INSERT INTO #temtable1
(referenceno,employeeid,ccode,amount)
VALUES('1005','2003','3003','11000.00');

INSERT INTO #temtable1
(referenceno,employeeid,ccode,amount)
VALUES('1001','2001','3004','10000.00');
INSERT INTO #temtable1
(referenceno,employeeid,ccode,amount)
VALUES('1003','2002','3005','10000.00');
INSERT INTO #temtable1
(referenceno,employeeid,ccode,amount)
VALUES('1005','2003','3006','10000.00');
CREATE TABLE #temtable2
(
    referenceno int,
    employeeid varchar(10),
    total float(10)
);

INSERT INTO #temtable2
(referenceno,employeeid,total)
VALUES('1001','2001',NULL);
INSERT INTO #temtable2
(referenceno,employeeid,total)
VALUES('1002','2002',NULL);
INSERT INTO #temtable2
(referenceno,employeeid,total)
VALUES('1003','2003',NULL);


DECLARE @cnt INT = 0;
DECLARE @total INT = 0;
WHILE @cnt <= 10
BEGIN
   SET @cnt = @cnt   1;

UPDATE #temtable2
SET @total =  @total   x1.amount,
    total = @total
    FROM(SELECT
         MAX(referenceno) as referenceno, 
         MAX(employeeid) as employeeid, 
         ccode as ccode, 
         SUM(amount) as amount
         FROM #temtable1
         WHERE
         ccode = CONCAT('30', CONCAT(CASE WHEN @cnt < 10 THEN '0' ELSE '' END , @cnt))
         GROUP BY
         employeeid,ccode) AS x1
 WHERE x1.employeeid = #temtable2.employeeid
        AND x1.amount < 25000
 END
 
 select * from #temtable2
  

Текущий результат:

введите описание изображения здесь

Ожидаемый результат:

введите описание изображения здесь

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

Запрос будет первым циклом, начинающимся с 3001, затем до 3010, и добавлять его последовательно, пока он не превысит 25000, но это для каждого employeeid.

Комментарии:

1. Не могли бы вы предоставить некоторые доступные образцы данных и ожидаемый результат?

2. Почему вы хотите использовать цикл `WHILE` в первую очередь? SQL — это язык, основанный на множествах, вы должны стремиться к решениям, основанным на множествах.

3. @Larnu точно. Вот почему я попросил образцы и желаемый результат. Моим первым предположением было бы изменить это на решение, основанное на функции window и неограниченное предыдущее… но, думаю, трудно сказать без реальных примеров.

4. @Tyron78 . . . Я бы посоветовал вам задать новый вопрос. Предоставьте примеры данных, желаемые результаты и объяснение логики, которую вы хотите реализовать. Пример кода хорош, но не заменяет понятного объяснения для людей.

5. @Tyron78 Я добавил новые детали, извиняюсь, я забыл добавить свои тестовые данные.