2017-06-03 7 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 = CustomerNameの私は、同じクエリで合計を取得できますか

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のような関数をテストしましたが、この関数はすべてのデータに適用されています(データはすべて年であり、特定の年ではありません - >適用されたため)。

答えて

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; 

私はあなたの古い変更したカンマ区切りである(1992年以降も「現代」)現代のANSI規格に合流し、唯一のあなたがからの結果を見たいのテーブルに参加しました。国や製品ファミリなどの条件は、私の意見ではWHERE句(または必要ならばON節)に属します。 2013などの数字は有効なエイリアス名ではありません。したがって、引用符を使用する必要があります: "2013"。

+0

ありがとう、私は答えの質に驚いており、実際に動作します。私はこの新しい標準を学ぶ良い本を知っているか、インターネットで検索するように私に勧めてもらえたら尋ねたいと思っていました。 @ThorstenKettner – BiteBat

+0

いいえ、申し訳ありませんが、私は推薦がありません。私はSQLを20年以上使っていて、主にGoogleやSOから学んでいます。しかし、これは一般的な推奨事項ではありません。私はw3schoolsを見て、間違いなくそれをお勧めしませんが、私はどちらか他の勧告もありません。 –

+0

どうもありがとうございました。 – BiteBat

0

私はあなたが顧客
ずに毎年すべての取引の合計を必要と理解している場合、私はあなたがtempereroryテーブルの手順で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

関連する問題