2013-04-12 3 views
1

Я работаю в SQL Server 2005, создавая хранимая процедура, чтобы извлекать данные о плательщике/биллинге из моей базы данных.Обновление хранимой процедуры SQL Server с помощью SUM на INNER JOIN

Хранимая процедура создает временную таблицу для передачи обратно в приложение (VB.NET). Первая часть вытаскивает каждую запись из таблицы баланса периода в таблицу темпа и затем определяет «возраст» баланса за этот период (текущий, 30 дней просрочки, 60 дней просрочки и т. Д.). Это прекрасно работает.

Теперь мне нужно определить количество дней, начисляемых за текущий период. Поэтому я вытаскиваю все записи из моей временной таблицы, где возраст «CUR». Количество дней хранится в отдельной таблице в моей базе данных под названием charge. В течение одного периода может быть многозарядная запись. В тех случаях я хочу получить сумму всех дней за этот период.

Например, у одного человека на период с 1 марта по 31 марта может быть 4 отдельных записи о расходах: первые записи имеют 3 дня, вторая запись - 6 дней, третья запись - 1 день, четвертая - 5 дней. То, что я хочу в своем временном столе, - это всего лишь одна запись для этого лица за этот период, со значением дня в 15.

В настоящее время процедура производит правильное количество дней для 3 человек (из 102 человек). 82 человека имеют NULL в течение нескольких дней. Есть несколько человек, где это было бы правильно, но определенно не 82 из них. У оставшихся людей, кажется, есть дни, которые увеличиваются случайным образом. Количество дней не может быть больше количества дней в месяце, но есть люди с столбцом дней, установленным на число в сотнях и даже тысячах.

Это связано с the question I posted yesterday, но это другая часть отчета.

Я был бы признателен за любую помощь, которую вы можете дать.

CREATE PROCEDURE [AgedPayorReport]  
    @VCurrStart  DATETIME 
AS 
BEGIN 
    SET NOCOUNT ON; 

    BEGIN TRY 

     CREATE TABLE #t_temp 
      (     
       bal      DECIMAL(11, 2), 
       period     DATETIME, 
       account_code   INT, 
       payor_code    INT, 
       plan_code    INT,   
       age      VARCHAR(10), 
       census_days    INT 
      )   

     DECLARE @VCurrEnd   DATETIME 
     DECLARE @V30Start   DATETIME 
     DECLARE @V60Start   DATETIME 
     DECLARE @V90Start   DATETIME 
     DECLARE @V120Start   DATETIME 
     DECLARE @V150Start   DATETIME 
     DECLARE @V180Start   DATETIME 
     DECLARE @V210Start   DATETIME 
     DECLARE @V240Start   DATETIME 

SET @VCurrEnd = DATEADD(DAY,-1,(DATEADD(MONTH,1,@VCurrStart))) 
SET @V30Start = DATEADD(month,-1,@VCurrStart) 
SET @V60Start = DATEADD(month,-2,@VCurrStart) 
SET @V90Start = DATEADD(month,-3,@VCurrStart) 
SET @V120Start = DATEADD(month,-4,@VCurrStart) 
SET @V150Start = DATEADD(month,-5,@VCurrStart) 
SET @V180Start = DATEADD(month,-6,@VCurrStart) 
SET @V210Start = DATEADD(month,-7,@VCurrStart) 
SET @V240Start = DATEADD(month,-8,@VCurrStart) 

INSERT INTO #t_temp 
      (     
       bal, 
       period,    
       age 
      )    
SELECT  
       b.ledger_bal, 
       b.period,    
       (SELECT CASE 
       WHEN period > @VCurrStart THEN 'ADV' 
       WHEN period = @VCurrStart THEN 'CUR' 
       WHEN period = @V30Start THEN '30' 
       WHEN period = @V60Start THEN '60' 
       WHEN period = @V90Start THEN '90' 
       WHEN period = @V120Start THEN '120' 
       WHEN period = @V150Start THEN '150' 
       WHEN period = @V180Start THEN '180' 
       WHEN period = @V210Start THEN '210' 
       WHEN period = @V240Start THEN '240' 
       WHEN period < @V240Start THEN '270' 
       END) 
      FROM balance b WITH(NOLOCK)   


SELECT * 
INTO #t_temp_CUR 
FROM #t_temp 
WHERE age = 'CUR' 


UPDATE t 
SET t.census_days = (charge.sum_days) 
FROM #t_temp_CUR t 
INNER JOIN 
    (
     SELECT account_code, SUM(days) AS sum_days 
     FROM charge WITH(NOLOCK) 
     GROUP BY account_code 
    ) as charge 
    ON charge.account_code = t.account_code 
INNER JOIN charge c WITH(NOLOCK) 
ON c.account_code = t.account_code 
AND c.payor_code = t.payor_code 
AND c.plan_code = t.plan_code 
WHERE c.start_date >= @VCurrStart 
AND c.end_date <= @VCurrEnd 
AND c.type = 'C' 
AND c.void <> 1 
AND c.days <> 0 
AND c.days IS NOT NULL 


END TRY 
    BEGIN CATCH 

    END CATCH 
END 

Edited добавить образец данных:

Existing период баланса таблицы:

account_code payor_code  plan_code  period  ledger_bal period_bal_code 
--------------------------------------------------------------------------------------------------------------- 
9421   493    224    2012-07-01 191.82  30813 
9420   6833   527    2012-07-01 767.28  30810 
9419   6533   510    2012-07-01 1400.00  30806 
9418   6533   510    2012-07-01 1400.00  30803 
9417   493    224    2012-07-01 959.10  30800 
9416   2193   340    2012-07-01 244.17  30794 
9416   8468   584    2012-07-01 1370.00  30795 
9416   8935   433    2012-07-01 250.00  30798 
9415   493    224    2012-07-01 1150.92  30791 
9414   6158   495    2012-07-01 2916.00  30788 
9413   6833   527    2012-07-01 6385.61  30785 
9412   6034   474    2012-07-01 8488.16  30781 
9412   8930   433    2012-07-01 800.00  30783 
9411   493    224    2012-07-01 7840.18  30777 
9410   8468   584    2012-07-01 6156.00  30776 

Некоторые соответствующие записи в таблице заряда:

account_code payor_code  plan_code charge_code start_date end_date quantity gross_amount net_amount  days void 
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
9413   6833   527   5070631  2012-07-21 2012-07-31 1   2508.00   6385.61   11  0 
9411   493    224   5070755  2012-07-16 2012-07-29 1   3192.00   6972.28   14  0 
9411   493    224   5070757  2012-07-30 2012-07-31 1   456.00   867.90   2  0 
9416   8468   584   5071869  2012-07-27 2012-07-31 1   1140.00   1620.00   5  0 
9418   6533   510   5072255  2012-07-28 2012-07-31 1   912.00   1400.00   4  0 
9417   493    224   5073818  2012-07-27 2012-07-31 1   1140.00   959.10   5  0 
9410   8468   584   5075878  2012-07-12 2012-07-30 1   4332.00   6156.00   19  0 
9420   6833   527   5076857  2012-07-28 2012-07-31 1   912.00   767.28   4  0 
9412   6034   474   5076991  2012-07-16 2012-07-16 1   228.00   580.51   1  0 
9412   6034   474   5076994  2012-07-17 2012-07-29 1   2964.00   7546.63   13  0 
9412   6034   474   5076997  2012-07-30 2012-07-31 1   456.00   1161.02   2  0 
9421   493    224   5077918  2012-07-31 2012-07-31 1   228.00   191.82   1  0 
9414   6158   495   5079045  2012-07-23 2012-07-31 1   2052.00   2916.00   9  0 
9419   6533   510   5079366  2012-07-28 2012-07-31 1   912.00   1400.00   4  0 
9415   493    224   5079418  2012-07-26 2012-07-31 1   1368.00   1150.92   6  0 
9410   8468   584   5084838  2012-07-12 2012-07-30 1   -4332.00  -6156.00  19  0 
9410   8468   584   5085112  2012-07-12 2012-07-30 1   4332.00   6156.00   19  0 
9413   6833   527   5085371  2012-08-01 2012-08-03 1   684.00   1741.53   3  0 
9413   6833   527   5085373  2012-08-04 2012-08-09 1   1368.00   1150.92   6  0 
9413   6833   527   5085375  2012-08-10 2012-08-31 1   5016.00   4220.04   22  0 

Так учитывание # 9411. Текущая хранимая процедура производит:

ledger_bal period  account_code payor_code  plan_code  age  census_days 
------------------------------------------------------------------------------------------------ 
7840.18  2012-07-01 9411   493    224    CUR   70 

Но я хочу, чтобы произвести:

ledger_bal period  account_code payor_code  plan_code  age  census_days 
    ------------------------------------------------------------------------------------------------ 
7840.18  2012-07-01 9411   493    224    CUR   16 
+1

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

+0

Выполняет ли какой-либо из этих зарядов в границах периодов перекрытия таблицы заплат? Если это так, это будет сложнее. Кроме того, в ваших данных таблицы Charge account, account_code 9410 выглядит так: есть плата за возврат или что-то в этом роде, потому что у вас в столбцах количества число и одинаковое (но отрицательное) число. Предположительно, 19 дней одного из них действительно отрицательные 19 дней, чтобы компенсировать положительные 19 дней. Я полагаю, вы хотите 0 дней для 9410, а не 19 или 38 дней? – Chud

+0

Нет, сборы строго разделены по периоду. Нет совпадений. Для учетной записи 9410 дни должны суммироваться один раз для каждого периода начала/окончания даты. Таким образом, учетная запись 9410 имеет три записи в таблице тарифов, но все начинается с 7/12 и заканчивается на 7/30, поэтому все сборы за тот же период. Счет 9410 должен иметь в общей сложности 19 дней. –

ответ

0

я, наконец, понял это.

Я создал другую таблицу под названием #t_days, содержащую только поля, необходимые для ссылки на таблицу заплат, плюс дни. Я по-прежнему выбираю текущие записи #t_temp в #t_temp_CUR, а затем связываю с тем, что в таблицу оплаты, чтобы вставить отдельные записи заплат в #t_days. Затем я запускаю инструкцию обновления и вытаскиваю SUM из census_days из #t_days. Теперь вы создаете правильное количество дней для каждой записи.

Спасибо!

CREATE PROCEDURE [AgedPayorReport]  
    @VCurrStart  DATETIME 
AS 
BEGIN 
    SET NOCOUNT ON; 

    BEGIN TRY 

     CREATE TABLE #t_temp 
      (     
       bal      DECIMAL(11, 2), 
       period     DATETIME, 
       account_code   INT, 
       payor_code    INT, 
       plan_code    INT,   
       age      VARCHAR(10), 
       census_days    INT 
      ) 

    CREATE TABLE #t_days 
      (    
       account_code   INT, 
       payor_code    INT, 
       plan_code    INT,     
       census_days    INT    
      ) 

     DECLARE @VCurrEnd   DATETIME 
     DECLARE @V30Start   DATETIME 
     DECLARE @V60Start   DATETIME 
     DECLARE @V90Start   DATETIME 
     DECLARE @V120Start   DATETIME 
     DECLARE @V150Start   DATETIME 
     DECLARE @V180Start   DATETIME 
     DECLARE @V210Start   DATETIME 
     DECLARE @V240Start   DATETIME 

SET @VCurrEnd = DATEADD(DAY,-1,(DATEADD(MONTH,1,@VCurrStart))) 
SET @V30Start = DATEADD(month,-1,@VCurrStart) 
SET @V60Start = DATEADD(month,-2,@VCurrStart) 
SET @V90Start = DATEADD(month,-3,@VCurrStart) 
SET @V120Start = DATEADD(month,-4,@VCurrStart) 
SET @V150Start = DATEADD(month,-5,@VCurrStart) 
SET @V180Start = DATEADD(month,-6,@VCurrStart) 
SET @V210Start = DATEADD(month,-7,@VCurrStart) 
SET @V240Start = DATEADD(month,-8,@VCurrStart) 

INSERT INTO #t_temp 
      (     
       bal, 
       period,    
       account_code, 
       payor_code, 
       plan_code, 
       age 
      )    
SELECT  
       b.ledger_bal, 
       b.period, 
       b.account_code, 
       b.payor_code, 
       b.plan_code, 
       (SELECT CASE 
       WHEN period > @VCurrStart THEN 'ADV' 
       WHEN period = @VCurrStart THEN 'CUR' 
       WHEN period = @V30Start THEN '30' 
       WHEN period = @V60Start THEN '60' 
       WHEN period = @V90Start THEN '90' 
       WHEN period = @V120Start THEN '120' 
       WHEN period = @V150Start THEN '150' 
       WHEN period = @V180Start THEN '180' 
       WHEN period = @V210Start THEN '210' 
       WHEN period = @V240Start THEN '240' 
       WHEN period < @V240Start THEN '270' 
       END) 
      FROM balance b WITH(NOLOCK)   


SELECT * 
INTO #t_temp_CUR 
FROM #t_temp 
WHERE age = 'CUR' 


INSERT INTO #t_days 
      (    
       account_code, 
       payor_code,    
       plan_code, 
       census_days 
      ) 
SELECT 
t.account_code, 
t.payor_code, 
t.plan_code, 
c.days 
FROM #t_temp_CUR t 
INNER JOIN br549.charge c WITH(NOLOCK) 
ON t.account_code = c.account_code 
AND t.payor_code = c.payor_code 
AND t.plan_code = c.plan_code 
WHERE c.type = 'C' 
AND c.advance = '' 
AND c.void <> 1 
AND c.start_date >= @vkVCurrStart 
AND c.end_date <= @vkVCurrEnd 


UPDATE #t_temp 
SET census_days = 
(SELECT SUM(census_days) 
FROM #t_days 
WHERE #t_days.account_code = #t_temp.account_code 
AND #t_days.payor_code = #t_temp.payor_code 
AND #t_days.plan_code = #t_temp.plan_code 
AND #t_days.period = #t_temp.period) 

SELECT * FROM #t_temp 


END TRY 
    BEGIN CATCH 

    END CATCH 
END