SQL具有计算值的其他行

时间:2019-02-22 10:51:23

标签: sql-server

我有以下结果集:

SELECT type, productid, source, product, term, milespa, maintained 
FROM pricing

type productid source  product term milespa maintained
car  75850     LENDER1 FL      2    8000    442.80
car  75850     LENDER1 FL      2    30000   532.70

该表仅包含8000和30000里程的价格。我需要更改查询,以便它计算介于两者之间的所有1000里程增量的价格,例如,要计算9000为:

(30000 - 8000) / 1000 = 22 --the number of increments
(532.70 - 442.80) = 89.90 --difference between 8k and 30k
--9000 price = 8000 price + the difference divided into increments so 442.80 + (89.90 / 22 * 1) = 446.88         
10000 would be 442.80 + (89.90 / 22 * 2) = 450.97

以此类推...

我可以这样做,这样一个查询将返回我需要的所有计算出的价格吗?

谢谢

2 个答案:

答案 0 :(得分:0)

我喜欢将问题分成小块(子查询或CTE)。您尚未包括表的定义,因此我无法对其进行全面测试,但是它应该为您提供了一个解决问题的好方法。

;WITH MissingMileages AS -- Generate all missing mileages from 9k to 30k in 1k increments (recursive CTE)
(
    SELECT
        MissingMileage = 9000

    UNION ALL

    SELECT
        MissingMileage = M.MissingMileage + 1000
    FROM
        MissingMileages AS M
    WHERE
        M.MissingMileage + 1000 < 30000
),
MaintainedPriceByIncrement AS -- Determine the maintained price for 1k increment by each key columns
(
    SELECT
        P8.productid,
        P8.type,
        P8.source,
        P8.product,
        P8.term,
        maintainedByIncrement = (P30.maintained - P8.maintained) / 22
    FROM
        pricing AS P8
        INNER JOIN pricing AS P30 ON 
            P8.productId = P30.productId AND
            P8.type = P30.type AND
            P8.source = P30.source AND
            P8.product = P30.product AND
            P8.term = P30.term
    WHERE
        P8.milespa = 8000 AND
        P30.milespa = 30000
),
AllAvailableProducts AS -- List all products to expand mileage (1 row per entity)
(
    SELECT DISTINCT
        P.productid,
        P.type,
        P.source,
        P.product,
        P.term,
    FROM
        pricing AS P
)
SELECT
    A.productid,
    M.MissingMileage,
    MissingMaintained = P.maintainedByIncrement * (M.MissingMileage / 1000)
FROM
    AllAvailableProducts AS A

    -- Expand all products with all missing mileages
    CROSS JOIN MissingMileages AS M

    -- ... and retrieve the increment by 1k mileage for that particular product
    INNER JOIN MaintainedPriceByIncrement AS P ON
        A.productId = P.productId AND
        A.type = P.type AND
        A.source = P.source AND
        A.product = P.product AND
        A.term = P.term

ORDER BY
    A.productid,
    M.MissingMileage

答案 1 :(得分:0)

让我知道是否有帮助。

您可以运行here进行验证。

我只是从原始表中提取了相关的列来完成这项工作。

根据您的需要进行调整。

create table #pricing (
productid int,
milespa int,
maintained smallmoney
);  
insert into #pricing VALUES(75850,8000,442.80); 
insert into #pricing VALUES(75850,30000,532.70); 
create table #mileage (
   miles smallint
);
insert into #mileage VALUES(8000);
insert into #mileage VALUES(9000);
insert into #mileage VALUES(10000);
insert into #mileage VALUES(11000);
insert into #mileage VALUES(12000);
insert into #mileage VALUES(13000);
insert into #mileage VALUES(14000);
insert into #mileage VALUES(15000);
insert into #mileage VALUES(16000);
insert into #mileage VALUES(17000);
insert into #mileage VALUES(18000);
insert into #mileage VALUES(19000);
insert into #mileage VALUES(20000);
insert into #mileage VALUES(21000);
insert into #mileage VALUES(22000);
insert into #mileage VALUES(23000);
insert into #mileage VALUES(24000);
insert into #mileage VALUES(25000);
insert into #mileage VALUES(26000);
insert into #mileage VALUES(27000);
insert into #mileage VALUES(28000);
insert into #mileage VALUES(29000);
insert into #mileage VALUES(30000);
WITH m8000 (productid, maintained8000) AS 
(
  select productid, maintained  
  FROM #pricing 
  WHERE productid = 75850
  AND   milespa =8000
),
m30000 (productid, maintained30000) AS
(
  select productid,maintained  
  FROM #pricing 
  WHERE productid = 75850
  AND   milespa =30000
),
maint (productid, per1000, starting) AS
(
select  m8.productid, ((m30.maintained30000 - m8.maintained8000) /22) AS per1000, m8.maintained8000
FROM m8000 m8
JOIN m30000 m30
ON m8.productid = m30.productid
)
select mt.productid, mi.miles, replace(cast((((mi.miles - 8000)/1000) * mt.per1000 + mt.starting) as numeric(10,2)),',','.')AS maintained
from maint mt
cross join #mileage mi

  • 请注意,“替换”部分可能对您而言不是必需的。

  • 这可能是REXTESTER。我只是不想逗号放在小数点后。