2017-06-03 93 views
1

我试图创建一个查询,它包含一个百分比。下面是表的结构:在同一个查询中获取一个条件的总数

STransaction:

TRANSACTIONID -> NUMBER(10,0) 
TRANSACTIONMONTH -> VARCHAR2(10 BYTE) 
CUSTOMER_CUSTOMERID -> NUMBER(8,0) 
COMMERCIALDESCRIPTION -> VARCHAR2(500 BYTE) 
AMOUNTTM -> NUMBER(8,2) 
AMOUNTDESCRIPTION -> VARCHAR2(50 BYTE) 
FOB -> NUMBER(10,2) 
FOBUNIT -> NUMBER(10,2) 
CFR -> NUMBER(10,2) 
CFRUNIT -> NUMBER(10,2) 
SUPPLIER_SUPPLIERID -> NUMBER(8,0) 
BOARDINGCOUNTRY -> VARCHAR2(50 BYTE) 
BOARDINDBAY -> VARCHAR2(400 BYTE) 
TRANSPORTATIONVIA -> VARCHAR2(50 BYTE) 
CUSTOMS -> VARCHAR2(50 BYTE) 
TRANSACTIONYEAR -> VARCHAR2(4 BYTE) 
TRANSACTIONDAY -> VARCHAR2(2 BYTE) 
CHAPTER -> VARCHAR2(3 BYTE) 
TARIFFHEADING -> NUMBER(12,0) 
PRODUCTFAMILY_PRODUCTFAMILYID -> NUMBER(5,0) 

客户:

CUSTOMERID -> NUMBER(8,0) 
CUSTOMERNAME -> VARCHAR2(80 BYTE) 
COUNTRY_COUNTRYID -> NUMBER(5,0) 
ISVDT -> CHAR(1 BYTE) 

供应商:

SUPPLIERID -> NUMBER(8,0) 
SUPPLIERNAME -> VARCHAR2(80 BYTE) 
SUPPLIERCOUNTRY -> VARCHAR2(50 BYTE) 

ProductFamily:

PRODUCTFAMILYID -> NUMBER(5,0) 
PRODFAMNAME -> VARCHAR2(60 BYTE) 

国家:

COUNTRYID -> NUMBER(5,0) 
COUNTRYNAME -> VARCHAR2(20 BYTE) 
REGION_REGIONID -> NUMBER(5,0) 
COUNTRYABBR -> VARCHAR2(5 BYTE) 

我需要做一个表,每一年的销售获得每个客户,这是由在STRANSACTION表中的列CFR代表的百分比。在下面的代码,我有一个查询,得到每个客户的销售额每年:

SELECT cus.customername c, 
SUM(CASE WHEN tran.transactionyear = 2013 THEN tran.cfr ELSE 0 END) 2013, 
SUM(CASE WHEN tran.transactionyear = 2014 THEN tran.cfr ELSE 0 END) 2014, 
SUM(CASE WHEN tran.transactionyear = 2015 THEN tran.cfr ELSE 0 END) 2015, 
SUM(CASE WHEN tran.transactionyear = 2016 THEN tran.cfr ELSE 0 END) 2016, 
SUM(CASE WHEN tran.transactionyear = 2017 THEN tran.cfr ELSE 0 END) 2017 
FROM Stransaction tran, Customer cus, Productfamily family, Country country 
WHERE tran.customer_customerid = cus.customerid AND cus.country_countryid = country.countryid 
AND tran.productfamily_productfamilyid = family.productfamilyid AND country.countryname = 'Germany' 
AND tran.transactionyear > 2012 AND tran.transactionyear < 2018 AND family.prodfamname = 'Bond-offset Paper' 
GROUP BY (cus.customername); 

百分比必须从每年的销售总额所有客户的获得。例如,2014年客户1的销售额占2014年所有客户总销售额的2014年客户1的销售额。最后您应该看到如下表格:

C =客户& & 1 =客户名称

C| 2013 | % | 2014 | % | 2015 | % | 2016 | % | 2017 | 
|-------|-------|-------|-------|-------|-------|-------|-------|------| 
1|165.250|100,00%|152.336|100,00%|136.540|100,00%|121.533|100,00%|80.345| 

我怎样才能获得总计在同一个查询?我测试了OVER等函数,但是这个函数应用于所有数据(并且数据是所有年份而不是特定年份 - >由于WHERE应用)。

回答

0

这应该是相当简单的。您可以通过SUM(value) OVER()获得所有记录的总和。因此:

SELECT 
    c, 
    "2013", ROUND("2013" * 100/SUM("2013") OVER(), 2) AS "2013 %", 
    "2014", ROUND("2014" * 100/SUM("2014") OVER(), 2) AS "2014 %", 
    "2015", ROUND("2015" * 100/SUM("2015") OVER(), 2) AS "2015 %", 
    "2016", ROUND("2016" * 100/SUM("2016") OVER(), 2) AS "2016 %", 
    "2017", ROUND("2017" * 100/SUM("2017") OVER(), 2) AS "2017 %" 
FROM 
(
    SELECT cus.customername c, 
    SUM(CASE WHEN tran.transactionyear = 2013 THEN tran.cfr ELSE 0 END) AS "2013", 
    SUM(CASE WHEN tran.transactionyear = 2014 THEN tran.cfr ELSE 0 END) AS "2014", 
    SUM(CASE WHEN tran.transactionyear = 2015 THEN tran.cfr ELSE 0 END) AS "2015", 
    SUM(CASE WHEN tran.transactionyear = 2016 THEN tran.cfr ELSE 0 END) AS "2016", 
    SUM(CASE WHEN tran.transactionyear = 2017 THEN tran.cfr ELSE 0 END) AS "2017" 
    FROM Stransaction tran, 
    JOIN Customer cus ON tran.customer_customerid = cus.customerid 
    WHERE tran.transactionyear BETWEEN 2013 AND 2017 
    AND cus.country_countryid = 
     (SELECT countryid FROM Country WHERE countryname = 'Germany') 
    AND tran.productfamily_productfamilyid = 
     (SELECT productfamilyid FROM Productfamily WHERE prodfamname = 'Bond-offset Paper') 
    GROUP BY (cus.customername) 
) 
ORDER BY c; 

我已经改变了旧的逗号分隔加入现代ANSI标准(以及“现代”自1992年以来即是)和才加入你想看到从结果表。诸如国家和产品族的条件属于我认为的WHERE条款(如果您愿意,也可以在ON条款中)。 2013等数字是没有有效的别名;你应该使用引号:“2013”​​。

+0

谢谢,我惊讶于答案的质量,它实际上工作。我想问你是否知道一本好书能够学习这个新标准,或者如果你推荐我在互联网上搜索。 @ThorstenKettner – BiteBat

+0

不,对不起,我没有任何建议。我一直在使用SQL大约二十年,现在主要从Google和SO学习。但这不是一般性建议。我已经看到了w3schools,绝对不会推荐,但我没有其他建议。 –

+0

我了解你,无论如何非常感谢你。 – BiteBat

0

如果我明白你需要的所有交易在每年总结未经客户
我认为你可以tempererory表过程做(计算和执行select)它由pl/sql language,但如果你希望只使用sql你应该使用cte例如像这样

with cte as (select cus.customername,tran.transactionyear,tran.cfr 
    from Stransaction tran, Customer cus, Productfamily family, Country country 
where tran.customer_customerid = cus.customerid 
    and cus.country_countryid = country.countryid 
    and tran.productfamily_productfamilyid = family.productfamilyid 
    and country.countryname = 'Germany' 
    and tran.transactionyear > 2012 
    and tran.transactionyear < 2018 
    and family.prodfamname = 'Bond-offset Paper' 
) 


select sel1.customername c, 
     sel1.year2013, 
     sel1.year2013 * 100/ sel2.year2013 perc2013, 
     sel1.year2014, 
     sel1.year2014 * 100/ sel2.year2014 perc2014, 
     sel1.year2015, 
     sel1.year2015 * 100/ sel2.year2015 perc2015, 
     sel1.year2016, 
     sel1.year2016 * 100/ sel2.year2016 perc2016, 
     sel1.year2017, 
     sel1.year2017 * 100/ sel2.year2017 perc2017 
from 
(select cte1.customername, 
     sum(decode(cte1.transactionyear,2013,cte1.cfr,0)) year2013, 
     sum(decode(cte1.transactionyear,2014,cte1.cfr,0)) year2014, 
     sum(decode(cte1.transactionyear,2015,cte1.cfr,0)) year2015, 
     sum(decode(cte1.transactionyear,2016,cte1.cfr,0)) year2016, 
     sum(decode(cte1.transactionyear,2017,cte1.cfr,0)) year2017 
    from cte cte1 
group by (cte1.customername)) sel1, 
(select sum(decode(cte2.transactionyear,2013,cte2.cfr,0)) year2013, 
     sum(decode(cte2.transactionyear,2014,cte2.cfr,0)) year2014, 
     sum(decode(cte2.transactionyear,2015,cte2.cfr,0)) year2015, 
     sum(decode(cte2.transactionyear,2016,cte2.cfr,0)) year2016, 
     sum(decode(cte2.transactionyear,2017,cte2.cfr,0)) year2017 
    from cte cte2 
) sel2 
+0

这是对的,但我认为查询,我标记为正确,更快,更容易维护 – BiteBat

相关问题