SQL加权收入查询

时间:2015-12-01 17:35:52

标签: sql-server sql-update

6我有3张桌子。以下示例。

Weight
Channel WeightFirst WeightMiddle    WeightLast
Dir      40         45              50
NatS     0          0               0
PC       20         25              30
UnRef    40         45              50

Sales
saleID  revenue
32150   1600.00
32153   516.00

Visits
visitID saleID  visitDate       channel visitRevenue
4479433 32153   2014-12-09 15:00:41.000 NatS    NULL
4479434 32153   2014-12-09 14:55:21.000 PC  NULL
4479435 32153   2014-12-09 15:09:01.000 UnRef   NULL
4755575 32150   2014-12-07 16:41:24.000 NatS    NULL
4756323 32150   2014-12-07 16:52:56.000 PC  NULL
4756324 32150   2014-12-06 20:49:41.000 Dir NULL

我需要根据权重表中的WeightFirst,WeightMiddle,WeightLast计算Visits表中的visitRevenus。

Visits表中的第一个visitDate获取WeightFirst,上一次visitDate获取WeightLast,这些日期之间的所有内容都获得WeightMiddle。

例如,saleID 32153的第一个visitDate为visitID 4479434,因此PC的WeightFirst为20,访问ID为4479433为NatS为0,访问ID为4479435为UnRef为50。总重量为70.销售额中的saleID收入为516.00 我需要将516.00除以70,然后将结果乘以每个权重,并使用该结果更新Visits表中的visitRevenue。

因此PC将获得147.4285714285714而UnRef将获得368.5714285714286。将它们加在一起,它就是516.

我只持有2个saleID,多个频道和大量的visitDates。我需要一些SQL来更新visitRevenue 有这些计算的数字,但我很难开始。任何帮助都是最受欢迎的!如果需要更多信息,请询问。

由于

1 个答案:

答案 0 :(得分:0)

我认为这就是诀窍。我不知道你的系统,所以我不知道你是否可以改变基础表,所以这可以用表变量做所有事情。

顺便说一下,真的有助于首先设置表格:)

DECLARE @weight TABLE (
        Channel varchar(max),
        WeightFirst int,
        WeightMiddle int,
        WeightLast int)

    INSERT INTO @weight VALUES  
    ('Dir', 40,45,50),
    ('NatS', 0, 0, 0),
    ('PC',  20,25,30),
    ('UnRef',40,45,50)

    DECLARE @sales TABLE (
        salesID int,
        revenue float)

    INSERT INTO @sales VALUES
     (32150,1600.00),
     (32153,516.00)

    DECLARE @visits TABLE (
        visitID int,
        salesID int,
        visitDate datetime,
        channel varchar(max),
        VisitRevenue float)

    INSERT INTO @visits VALUES 
    (4479433, 32153,   '2014-12-09 15:00:41.000','NatS', NULL),
    (4479434, 32153,   '2014-12-09 14:55:21.000','PC',   NULL),
    (4479435, 32153,   '2014-12-09 15:09:01.000','UnRef',NULL),
    (4755575, 32150,   '2014-12-07 16:41:24.000','NatS', NULL),
    (4756323, 32150,   '2014-12-07 16:52:56.000','PC',   NULL),
    (4756324, 32150,   '2014-12-06 20:49:41.000','Dir',  NULL)


    DECLARE @visitWeight TABLE (
        visitID int,
        salesID int,
        visitDate datetime,
        channel varchar(max),
        VisitRevenue float,
        visitNumber int,
        visitWeight int,
        totalWeight float,
        revenue float)

    INSERT INTO @visitWeight
    SELECT visitID, v.salesID, visitDate,channel,visitRevenue,
        ROW_NUMBER() OVER (PARTITION BY v.salesID ORDER BY visitDate ASC) AS visitNumber ,NULL,NULL, revenue
    FROM @visits v JOIN @sales s ON v.salesID=s.salesID

    UPDATE @visitWeight -- this sets the first weight, also sets everything else to middle
    SET visitWEIGHT =
        CASE WHEN visitNumber=1 THEN WeightFirst ELSE weightMiddle END  
    FROM @visitWeight vw JOIN @weight w on vw.channel=w.channel


    UPDATE @visitWeight -- this sets the last weight
    SET visitWEIGHT = WeightLast
    FROM
        (SELECT salesID, max(visitNumber) AS maxVisit FROM @visitWeight GROUP BY salesID) AS t
        JOIN @visitWeight vw ON t.maxVisit=vw.visitNumber JOIN
        @weight w on vw.channel=w.channel

    UPDATE @visitWeight
    SET totalWeight = s.sumWeight,
        VisitRevenue = revenue/s.sumWeight*visitWeight 
    FROM (SELECT salesID, SUM(visitWeight) AS sumWeight FROM @visitWeight GROUP BY salesID) AS s

    SELECT * FROM @visitWeight order by salesID, visitDate