简体   繁体   English

在sql中加入计算

[英]Calculate in join in sql

I am trying to achieve staggered calculation in joins in sql 2008. I can have n number of rows for 1 job id.我正在尝试在 sql 2008 的连接中实现交错计算。我可以为 1 个作业 ID 设置 n 行。 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:现在JobID = 1的折扣是 80 ,所以我期望的查询结果输出如下:

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.如果Amount > Discount ,则显示finalvalue = Amount - Discount但如果Amount < Discount ,则显示Finalvalue = Amount - Amount ,如果Discount仍然存在,则从后续行中扣除相同的值。

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

Can all this be done in a join?所有这些都可以在一个连接中完成吗?

Here you are:给你:

EDIT: ATTENTION: You should add a column for sorting.编辑:注意:您应该添加一列进行排序。 My approach is partitioning AND sorting by JobID which makes the output random...我的方法是按 JobID 进行分区和排序,这使得输出随机......

EDIT: Sorry, did not add the tables...编辑:对不起,没有添加表格...

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)

Hope this helps希望这可以帮助

I think what you are looking for can be done using a case statement我认为您正在寻找可以使用案例陈述来完成

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

from Job a inner join Job_discount b on a.jobid = b.jobid从 Job a 内部加入 Job_discount b on a.jobid = b.jobid

You can look at the results here http://sqlfiddle.com/#!3/f9a46/1您可以在这里查看结果http://sqlfiddle.com/#!3/f9a46/1

I had to assume the discount table structure我不得不假设折扣表结构

I added some sequence (row number) for the Job table (calling it JobOrder), to increment the sums.我为 Job 表(称为 JobOrder)添加了一些序列(行号),以增加总和。 You can change the order as it is now for JobId, Amount!您可以像现在一样更改 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; 

Asuming that your Discount table is something like:假设您的折扣表类似于:

CREATE TABLE Discount (
    JobID INT,
    Discount INT 
);

SqlFiddle here! SqlFiddle 在这里! and for a more secure Sql (checking null values and see the discount left) see this SQLFiddle too .对于更安全的 Sql(检查空值并查看剩余折扣),请参阅此SQLFiddle

在此处输入图像描述

A version which keeps track of the discount left, see sqlfiddle-2 above.跟踪剩余折扣的版本,请参见上面的 sqlfiddle-2。

在此处输入图像描述

You can try following code : 80 is the discount amount您可以尝试以下代码:80 是折扣金额

Select JobID,  Amount,
case when SUM (Amount) OVER (partition by JobID ORDER BY JobID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) > 80 then SUM(Amount) OVER (partition by JobID ORDER BY JobID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) - 80 else 0 end as FinalValue
from Job

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM