2017-06-03 53 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

相關問題