我的数据库有一个主表(例如Table_A
)。第1列包含项目的名称,第6列是我的数据行的日期。第7列是第1列的项目类型,从A到z。
例如(某些Table_A
行):
|item_1 |200 |120 |300 |40 |201702 |type_A |
|item_2 |210 |320 |340 |10 |201702 |type_A |
|item_1 |150 |30 |70 |38 |201703 |type_A |
|item_2 |315 |220 |120 |40 |201703 |type_A |
|item_3 |40 |500 |110 |35 |201702 |type_B |
|item_4 |758 |78 |152 |61 |201702 |type_B |
|item_3 |778 |920 |12 |330 |201703 |type_B |
|item_4 |315 |220 |120 |40 |201703 |type_B |
我希望显示第7列中每个类型的项目,从特定日期(ex.201703)开始,然后在第2列的总和,第3列的总和,第4列的总和,第5列的总和,然后在下面在函数内计算的增长率(((月的总和/上个月的总和)* 100)-100)
对于上面的例子,我期望的结果是:
|item_1 |150 |30 |70 |38 |201703 |type_A |
|item_2 |315 |220 |120 |40 |201703 |type_A |
|sum |465 |250 |190 |78 |201703 |type_A |
|rate |13.1 |-43.1|-74.3|56 |201703 |type_A |
|item_3 |778 |920 |12 |330 |201703 |type_B |
|item_4 |315 |220 |120 |40 |201703 |type_B |
|sum |1093 |1140 |132 |370 |201703 |type_B |
|rate |36.96|97.23|-18.5|285.4|201703 |type_B |
我试过这段代码:
(
SELECT
col1, col2, col3, col4, col5, col6, col7
FROM
Table_A
INNER JOIN
Table_B ON Table_A.col1 = Table_B.col1
WHERE
Table_A.col6 = 201703 AND (Table_A.col7 = 'type_A')
)
UNION ALL
(
SELECT
'sum', SUM(col2), SUM(col3), SUM(col4), SUM(col5), 201703, 'type_A'
FROM
Table_A
INNER JOIN
Table_B ON Table_A.col1 = Table_B.col1
WHERE
Table_A.col6 = 201703 AND (Table_A.col7 = 'type_A')
) --sum of data with 'g'
UNION ALL
(
SELECT
N'Rate',
(ROUND(((((SELECT CONVERT (FLOAT, SUM(col2))
FROM Table_A
WHERE Table_A.col6 = 201703 AND (Table_A.col7 = 'type_A')
) /
(SELECT CONVERT (FLOAT, SUM(col2))
FROM Table_A
WHERE Table_A.col6 = (201703 - 1) AND (Table_A.col7 = 'type_A')
)
) * 100
) - 100), 2)),
(ROUND(((((SELECT CONVERT (FLOAT, SUM(col3))
FROM Table_A
WHERE Table_A.col6 = 201703 AND (Table_A.col7 = 'type_A')
) /
(SELECT CONVERT (FLOAT, SUM(col3))
FROM Table_A
WHERE Table_A.col6 = (201703 - 1) AND (Table_A.col7 = 'type_A')
)
) * 100
) - 100), 2)),
(ROUND(((((SELECT CONVERT (FLOAT, SUM(col4))
FROM Table_A
WHERE Table_A.col6 = 201703 AND (Table_A.col7 = 'type_A')
) /
(SELECT CONVERT (FLOAT, SUM(col4))
FROM Table_A
WHERE Table_A.col6 = (201703 - 1) AND (Table_A.col7 = 'type_A')
)
) * 100
) - 100), 2)),
(ROUND(((((SELECT CONVERT (FLOAT, SUM(col5))
FROM Table_A
WHERE Table_A.col6 = 201703 AND (Table_A.col7 = 'type_A')
) /
(SELECT CONVERT (FLOAT, SUM(col5))
FROM Table_A
WHERE Table_A.col6 = (201703 - 1) AND (Table_A.col7 = 'type_A')
)
) * 100
) - 100), 2)),
NULL,
'type_A'
)
但此代码仅显示第7列中的一种类型
答案 0 :(得分:2)
select
item
,co11
,col2
,col3
,col4
,date
,type
from
table_a
union
select
"sum" as item
,sum(col1) as sc1
,sum(col2) as sc2
,sum(col3) as sc3
,sum(col4) as sc4
,date
,type
from
table_a
group by
type
,date
union
select
"rate" as item
,round(((c.sc1-p.sc1)*100)-100,2)
,round(((c.sc2-p.sc2)*100)-100,2)
,round(((c.sc3-p.sc3)*100)-100,2)
,round(((c.sc4-p.sc4)*100)-100,2)
,date
,type
from
(
select
,sum(col1) as sc1
,sum(col2) as sc2
,sum(col3) as sc3
,sum(col4) as sc4
,date
,type
from
table_a
group by
type
,date
) as c
left outer join (
select
,sum(col1) as sc1
,sum(col2) as sc2
,sum(col3) as sc3
,sum(col4) as sc4
,date
,type
from
table_a
group by
type
,date
) as p
on c.type = p.type
and (1,cast(c.date as int)) = (1,cast(p.date as int))+1
在DB中执行此操作也有点奇怪..通常更容易使用两个或三个查询并将数据放在其他地方 - 特别是因为每个列中有不同的内容而你可能会必须将整个事物包装在另一个选择中以获得使其有效的顺序:
select
item
,co11
,col2
,col3
,col4
,date
,type
from(
select
item
,co11
,col2
,col3
,col4
,date
,type
,0 as sortSeq
from
table_a
union
select
"sum" as item
,sum(col1) as sc1
,sum(col2) as sc2
,sum(col3) as sc3
,sum(col4) as sc4
,date
,type
,1 as sortSeq
from
table_a
group by
type
,date
union
select
"rate" as item
,round(((c.sc1-p.sc1)*100)-100,2)
,round(((c.sc2-p.sc2)*100)-100,2)
,round(((c.sc3-p.sc3)*100)-100,2)
,round(((c.sc4-p.sc4)*100)-100,2)
,date
,type
,3 as sortSeq
from
(
select
,sum(col1) as sc1
,sum(col2) as sc2
,sum(col3) as sc3
,sum(col4) as sc4
,date
,type
from
table_a
group by
type
,date
) as c
left outer join (
select
,sum(col1) as sc1
,sum(col2) as sc2
,sum(col3) as sc3
,sum(col4) as sc4
,date
,type
from
table_a
group by
type
,date
) as p
on c.type = p.type
and (1,cast(c.date as int)) = (1,cast(p.date as int))+1
) as a
order by
date
,type
,sortSeq
,item
答案 1 :(得分:0)
这是完整的工作示例。如果需要,您可以添加一些订购:
DECLARE @DataSource TABLE
(
[col1] VARCHAR(12)
,[col2] INT
,[col3] INT
,[col4] INT
,[col5] INT
,[col6] VARCHAR(12)
,[col7] VARCHAR(12)
);
INSERT INTO @DataSource ([col1], [col2], [col3], [col4], [col5], [col6], [col7])
VALUES ('item_1', 200, 120, 300, 40 , 201702, 'type_A')
,('item_2', 210, 320, 340, 10 , 201702, 'type_A')
,('item_1', 150, 30 , 70 , 38 , 201703, 'type_A')
,('item_2', 315, 220, 120, 40 , 201703, 'type_A')
,('item_3', 40 , 500, 110, 35 , 201702, 'type_B')
,('item_4', 758, 78 , 152, 61 , 201702, 'type_B')
,('item_3', 778, 920, 12 , 330, 201703, 'type_B')
,('item_4', 315, 220, 120, 40 , 201703, 'type_B');
DECLARE @curr_month VARCHAR(12) = '201703'
,@prev_month VARCHAR(12) = '201702';
SELECT ISNULL([col1], 'sum')
,SUM([col2])
,SUM([col3])
,SUM([col4])
,SUM([col5])
,[col6]
,[col7]
FROM @DataSource
WHERE [col6] = @curr_month
GROUP BY GROUPING SETS
(
([col1], [col6], [col7])
,([col6], [col7])
)
UNION ALL
SELECT 'Rate'
,CAST((SUM(IIF([col6] = @curr_month, [col2], 0.0)) / SUM(IIF([col6] = @prev_month, [col2], 0.0)) * 100) - 100 AS DECIMAL(9,2))
,CAST((SUM(IIF([col6] = @curr_month, [col3], 0.0)) / SUM(IIF([col6] = @prev_month, [col3], 0.0)) * 100) - 100 AS DECIMAL(9,2))
,CAST((SUM(IIF([col6] = @curr_month, [col4], 0.0)) / SUM(IIF([col6] = @prev_month, [col4], 0.0)) * 100) - 100 AS DECIMAL(9,2))
,CAST((SUM(IIF([col6] = @curr_month, [col5], 0.0)) / SUM(IIF([col6] = @prev_month, [col5], 0.0)) * 100) - 100 AS DECIMAL(9,2))
,@curr_month
,[col7]
FROM @DataSource
WHERE EXISTS(SELECT 1 FROM @DataSource DS WHERE DS.[col1] = [col1] AND [col6] = @curr_month)
GROUP BY [col7];
您也可以使用DECIMAL
投射 - 目前,我正在投放到DECIMAL(9,2)
,但您可以更改查询以符合您的需求。
另外,请注意我已添加到变量以保存当前和上个月。它们也可以用SQL填充,但我对它们进行了硬编码。