2015-07-10 74 views
3

我想在sql 2008中的连接中实现交错计算。我可以有1个工作id的n行数。我已经创建了下面在计算加入sql

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); 

现在JobID = 1的折扣是80,那么我期待在查询结果的输出下面是一个例子:

如果Amount > Discount,所以显示finalvalue = Amount - Discount 但如果Amount < Discount ,则显示Finalvalue = Amount - Amount, 并且如果Discount仍然存在,则从后续行中扣除相同的值。

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

所有这些都可以在连接中完成吗?

+3

请包括折扣表的结构,以便制定正确的答案。 – dnapierata

+3

您是否有ID或创建日期字段可用于说明折扣应用的订单?例如,在您的示例中,您是如何决定在将25行和45行应用到40行之前应用折扣的? – APH

回答

0

您在这里:

编辑:注意:您应该添加一个列进行排序。我的办法是分区和作业ID,这使得输出随机排序...

编辑:对不起,没有添加表...

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) 

希望这有助于

0

我想你正在寻找可以使用CASE语句,

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

从工作做一个内部联接Job_discount b关于a.jobid = b.jobid

你可以看一下这里的结果http://sqlfiddle.com/#!3/f9a46/1

我不得不承担的折扣表结构

+0

你的SQLFiddle是否真的返回OP的数据?我理解OP的方式是需要完成一笔额外的工作,比“Discount”更好的词可以是“Acconto”... ... – Shnugo

+0

Vanamali,Apprecciate我们的努力......但是我希望你的文章可以毫不含糊地减去折扣从数量...这种情况..我必须照顾所有的项目... –

0

我加了一些序列(行号)的工作表(称之为JobOrder),递增金额。您可以更改订单,因为它现在是JobId,金额!

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; 

Asuming你的折扣表是这样的:

CREATE TABLE Discount (
    JobID INT, 
    Discount INT 
); 

SqlFiddle here!和更安全的SQL(检查空值和左看看折扣)看到这个SQLFiddle too

enter image description here

其中跟踪离开折扣的一个版本,见sqlfiddle-2的上方。

enter image description here

+0

嗨简单,Thans为你的努力..你的答案是非常接近,但它在几个场景中打破...例如,如果我在JOB表中添加了另一行,如(1,50)...它将打破..直到折扣剩下的点nt变为0,您的查询就像是一种享受... –

+0

嗨@XanderKage我不明白你的评论。如何在jobid 1中增加50的额外值?我检查了sqlfiddle http://sqlfiddle.com/#!6/58efd7/1,它的作用就像魅力,discountleft匹配和finalvalue是正确的;)或者您是否期望finalvalue incr呢?就像jobid 1一样,它会像0,0,30,然后是50? – MrSimpleMind

+0

HI SImple,我的坏..它工作正常,但我发现1个情况,它打破:(让我们假设折扣是最低的金额..在临时工情况下它打破了...我更新折扣为5 JOB ID = 4来测试它...欣赏你的努力tho .. –