Sql Server - 根据条件运行总计

时间:2014-09-22 13:06:45

标签: tsql sql-server-2012

我一直在试图找出正确的逻辑(SQL Server 2012)来实现我想象的相当常规的东西,但我无法在任何地方找到任何这样的例子。基本上,我在表中有3列:product,flag,value。产品可以在表中多次列出,但只有一次带有唯一标志(即product1可以使flag1或flag2具有不同/相同但不会有2条记录,其中product1和flag1以及不同/相同的值) 。

该标志代表一个预定义的值(1,2,3,4),该字段背后的意图是能够根据该标志的值分配一个唯一的数学方程式。最终结果将产生单个产品,唯一标志和基于数学方程输出的新累积总数。例如,假设product1被列出4次,其标志值为flag1,flag2,flag3,flag4(见下文):

Product-----Flag-----Value
Product1----Flag1----1.00
Product1----Flag2----3.00
Product1----Flag3----5.00
Product1----Flag4----7.00

Product-----Flag-----Value
Product1----Flag1----1.00  (flag1 value)
Product1----Flag2----4.00  (flag1+flag2 value)
Product1----Flag3----6.00  (flag1+flag3 value)
Product1----Flag4----10.00 (flag2+flag4 value)

Flag1仅定义为add flag1。 Flag2定义为add flag1和flag2。标志3被定义为add flag1和flag 3.标志4被定义为add flag2和flag4。新的输出将是product1列出四次,其标志值为flag1,flag2,flag3,flag4,但新值为flag1,flag1_flag2,flag1 + flag3,flag2 + flag4。

我试图通过case语句应用逻辑,但我无法弄清楚如何遍历每个条件的所有产品,我试图使用运行总计解决方案,但我不知道如何合并将条件标记到其中,因此它仅在这些条件为真时执行运行总计。任何帮助和/或文章帮助我走上正确的道路将不胜感激。

3 个答案:

答案 0 :(得分:1)

虽然我不确定我完全理解你的问题,但我认为这可能是你想要的。为了实现这个目的,它假定当标志1到3时,flag1总是存在,而当flag4是时,flag1就存在。

;with cte as (
    select 
       product, 
       max(case when flag = 'Flag1' then Value end) as f1Value,
       max(case when flag = 'Flag2' then Value end) as f2Value,
       max(case when flag = 'Flag3' then Value end) as f3Value,
       max(case when flag = 'Flag4' then Value end) as f4Value
    from flags group by Product
)

select 
    flags.Product,
    flags.Flag,
    flags.Value as "Org. value",
    case flag 
       when 'Flag1' then f1Value 
       when 'Flag2' then f1Value + f2Value
       when 'Flag3' then f1Value + f3Value
       when 'Flag4' then f2Value + f4Value
       else flags.Value -- take the present value when flag is not Flag1-4
     end as "New value"    
from flags
inner join cte on flags.Product = cte.Product

请查看此Sample SQL Fiddle以查看其实际效果。

答案 1 :(得分:0)

我假设并尝试了Range值。

CREATE TABLE #tmp (Product VARCHAR(10), flag VARCHAR(10),value numeric(13,2))
GO
INSERT INTO #tmp
    SELECT 'Product1' , 'Flag1',1
    UNION
SELECT 'Product1' , 'Flag2',3
    UNION
SELECT 'Product1' , 'Flag3',5
    UNION
SELECT 'Product1' , 'Flag4',7
GO
            ;WITH cte
            AS
    (
    SELECT row_number () OVER(
            ORDER BY flag)  'row',*
        FROM #tmp
    )
SELECT  *,value 'RT'
    FROM    cte
    WHERE    row = 1
    UNION
SELECT    * ,(
    SELECT  cte.value
        FROM cte
        WHERE row  = 1
    )                    + value 'RT'
    FROM cte
    WHERE row BETWEEN 2 
        AND 3
    UNION
SELECT    * ,(
    SELECT  cte.value
        FROM cte
        WHERE row  =2
    )                    + value 'RT'
    FROM cte
    WHERE row >3
GO
DROP TABLE #tmp

答案 2 :(得分:0)

您可以将表格连接到自身,并适当选择条件:

SELECT p1.product,p1.Flag,p1.Value + COALESCE(p2.Value,0)
FROM
    Products p1
        left join
    Products p2
        on
           p1.Product = p2.Product and
           p2.Flag = CASE p1.Flag
                       --1 doesn't need a previous value
                       WHEN 2 THEN 1
                       WHEN 3 THEN 1
                       WHEN 4 THEN 2
                     END