Calculate in join in sql

时间:2015-07-10 20:34:40

标签: sql sql-server sql-server-2008

I am trying to achieve staggered calculation in joins in sql 2008. I can have n number of rows for 1 job id. I have created a sample below

CREATE TABLE Job
(
  JobID INT NOT NULL,
  Amount INT NOT NULL
);

INSERT INTO Job (JobID, Amount)
    VALUES (1, 25),
        (1, 45),
        (1, 40),
        (2, 25),
        (3, 26),
        (3, 26);

now the discount for JobID = 1 is 80 , So what I am expecting in output of query result is below:

If the Amount > Discount , so show the finalvalue = Amount - Discount but if Amount < Discount , then show Finalvalue = Amount - Amount , and if Discount is still left , deduct the same from the subsequent rows.

Job ID  Amount  FinalValue
1        25       0
1        45       0
1        40      30

Can all this be done in a join?

3 个答案:

答案 0 :(得分:0)

你在这里:

编辑:注意:您应该添加一列进行排序。我的方法是按JobID进行分区和排序,使输出随机...

编辑:抱歉,没有添加表格......

CREATE TABLE Job
(
    JobID INT NOT NULL,
    Amount INT NOT NULL
);

INSERT INTO Job (JobID, Amount)
    VALUES (1, 25), (1, 45), (1, 40), (2, 25), (3, 26), (3, 26);

CREATE TABLE Discount
(
    JobID INT NOT NULL,
    Discount INT NOT NULL
);
INSERT INTO Discount(JobID,Discount)VALUES(1,80),(2,0),(3,10);
    WITH myCTE AS
    (
        SELECT ROW_NUMBER() OVER(PARTITION BY Job.JobID ORDER BY Job.JobID) AS inx
              ,Job.JobID
              ,Job.Amount
              ,Discount.Discount     
        FROM Job
        INNER JOIN Discount ON Job.JobID=Discount.JobID
    )
    SELECT * FROM myCTE
    CROSS APPLY
    (
        SELECT SUM(x.Amount)
        FROM myCTE AS x
        WHERE x.JobID=myCTE.JobID
          AND x.inx<=myCTE.inx  
    ) AS AmountCummulativ(AmountCummulativ)
    CROSS APPLY(SELECT AmountCummulativ-myCTE.Discount) AS DiscountCalculated(DiscountCalculated)
    CROSS APPLY(SELECT CASE WHEN DiscountCalculated<0 THEN 0 ELSE DiscountCalculated END) AS DiscountResolved(DiscountResolved)

希望这有帮助

答案 1 :(得分:0)

我认为您正在寻找的是使用案例陈述

select a.jobid,a.Amount,case when a.amount > b.discount then a.amount - b.discount else 0 end final_value

来自Job a内部联接Job_discount b on a.jobid = b.jobid

您可以在此处查看结果http://sqlfiddle.com/#!3/f9a46/1

我必须假设折扣表结构

答案 2 :(得分:0)

我为Job表添加了一些序列(行号)(称为JobOrder),以增加总和。您现在可以更改JobId,Amount!

的订单
With JobOrder as (
  -- Job order by id and amount
  select row_number() over (order by JobID, Amount asc) as rowno, JobId, Amount from Job
),
JobSumIncr as (
  select 
  JobID, 
  Amount, 
  (select sum(Amount)
   from JobOrder j2
   where j2.JobID = j.JobID and j2.RowNo <= j.RowNo
  ) as AmountTotal
  from JobOrder j
)
select 
  j.JobID,
  j.Amount,
  j.AmountTotal,
  d.Discount,
  (case when d.Discount>=j.AmountTotal then 0 else j.AmountTotal-d.Discount end) as FinalValue
from
  JobSumIncr j left join Discount d on j.JobID = d.JobID; 

假设您的折扣表类似于:

CREATE TABLE Discount (
    JobID INT,
    Discount INT 
);

SqlFiddle here! 以及更安全的Sql(检查空值并查看折扣)请参阅 SQLFiddle too

enter image description here

跟踪折扣的版本,请参阅上面的sqlfiddle-2。

enter image description here