获取同一查询中的条件总数

时间:2017-06-03 04:47:21

标签: sql oracle

我试图创建一个查询,其中包含一个百分比。这是表格的结构:

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年客户1的销售额占2014年所有客户的总销售额。最后,您应该看到如下表格:

C = Customer&amp;&amp; 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这样的函数,但是这个函数适用于所有数据(并且数据是所有年份而不是特定年份的数据 - &gt;由于应用了WHERE)。

2 个答案:

答案 0 :(得分:0)

如果我知道你需要每年都没有客户的所有交易总和 我认为你可以通过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

答案 1 :(得分: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标准(以及#34;现代&#34;自1992年以来)并且只加入了您想要查看结果的表格。国家和产品系列等条件在我看来属于WHERE条款(如果您愿意,则属于ON条款)。 2013年等数字是无效的别名;你应该使用引号:&#34; 2013&#34;。