2015-04-07 46 views
2

我有一些表像下面的例子:查詢爲具有良好性能的許多列calculationg百分比

[myCategory]      [mySales] 
+------+---------+    +------------+-----+--------+-------+ 
| id | name |    | date  | cat | price | code | 
+------+---------+    +------------+-----+--------+-------+ 
| 1 | cat1 |    | 2015/01/01 | 1 | 25000 | 2  | 
| 2 | cat2 |    | 2015/01/01 | 2 | 32000 | 4  | 
| 3 | cat3 |    | 2015/02/01 | 1 | 25000 | 6  | 
| 4 | cat4 |    | 2015/02/01 | 3 | 40000 | 4  | 
: .. : ...  :    : ...  : .. :  : .. : 
+------+---------+    +------------+-----+--------+-------+ 
    \---------------- Foreign Key ----------------/ 

我試圖得到這樣的結果:

[results are between @fromDate and @toDate] 
+------+-----------+-----------+-------------+---------------+-...-+ 
| code | totalSale | prcntSale | ttlSaleCat1 | prcntSaleCat1 | ... | 
+------+-----------+-----------+-------------+---------------+-...-+ 
| 2 | 25000  | 20  | 25000  | 50   | ... | 
| 4 | 72000  | 60  | 0   | 0    | ... | 
| 6 | 25000  | 20  | 25000  | 50   | ... | 
: .. : ...  : ..  : ...   : ..   : ... : 
+------+-----------+-----------+-------------+---------------+-...-+ 

我的問題是關於計算百分比。

現在我已經宣佈了一些變量在我的存儲每個類別的程序,並收集總各ttlSaleN列,然後在主查詢使用它們,我的解決方案應該變得更快了,我想我應該改變我的解決辦法。

我的查詢是這樣的:

Declare @totalSale money = (select sum(s.price) 
          from mySales s 
          where s.date Between @fromDate and @toDate) 
Declare @ttlSale1 money = (select sum(s.price) 
          from mySales s 
          where s.date Between @fromDate and @toDate and s.cat = 1) 
... 
select s.code, sum(s.price) as totalSale, sum(s.price) * 100/@totalSale as prcntSale 
       sum(case s.cat when 1 then s.price else 0 end) as ttlSaleCat1, sum(case s.cat when 1 then s.price else 0 end) * 100/@ttlSale1 as prcntSaleCat1 
from mySales s 
where s.date Between @fromDate and @toDate 
group by s.code 

所有這些數據樣本那些我寫他們剛纔,如果這些有任何問題,忽略它們)。

我認爲對所有計算使用單個查詢可以使其更快 - 刪除變量 - 如果我的方式不對,請指導我以正確的方式。

+1

這是有點不清楚。你做單一陳述有問題嗎?如果不是,則只需製作另一個查詢並進行比較。如果不在生產環境中運行這兩個查詢,我們怎麼能假設一些查詢比其他更好呢? –

+0

@GiorgiNakeuri我將刪除那些計算總和值來計算百分比的變量。 –

+0

這是非常基本的原始查詢。我認爲你更好地通過索引和統計來優化,而不是通過優化那個查詢。 –

回答

1

對不起,這比我平常寫的要慢,但我衝過去了。我建議嘗試這樣的事情雖然:

declare @myCategory as table(id int, name varchar(10)) 
declare @mySales as table(date datetime, cat int, price float, code int) 
declare @fromDate as datetime = '2015-01-01' 
declare @toDate as datetime = '2015-02-02' 

insert into @myCategory 
values 
    (1, 'Cat1') 
    ,(2, 'Cat2') 
    ,(3, 'Cat3') 
    ,(4, 'Cat4') 
insert into @mySales 
values 
    ('2015-01-01', 1, 25000, 2) 
    ,('2015-01-01', 2, 32000, 4) 
    ,('2015-02-01', 1, 25000, 6) 
    ,('2015-02-01', 3, 40000, 4) 


SELECT  S.code, sum(totalSale) as totalSale, sum(totalSale) * 100/prcntSale as prcntSales, 
      sum(ttlSaleCat1) as ttlSaleCat1, sum(ttlSaleCat1) * 100/prcntSaleCat1 as prcntSaleCat1 
FROM 
    (
    select  s.code, 
       s.price as totalSale, 
       sum(s.price) over(partition by 1) as prcntSale, 
       case s.cat when 1 then s.price else 0 end as ttlSaleCat1, 
       sum(case when s.cat = 1 then SUM(s.price) end) over(partition by 1) as prcntSaleCat1 
    from  @mySales s 
    where  s.date Between @fromDate and @toDate 
    group by s.code, PRICE, CAT 
    ) AS S 
group by s.code, prcntSale, prcntSaleCat1