2012-05-17 62 views
2

我有SQL查詢,它工作正常。是否可以有動態的COUNT(CASE WHEN)語句?

select monthname (timestamp_iso(STATUSDATE)), 

    count (case when service='ADSL' then 1 end) as ADSL, 
    count (case when service='IPTV' then 1 end) as IPTV, 
    count (case when service='VOIP' then 1 end) as VOIP 
from INCIDENT 
group by monthname(timestamp_iso(STATUSDATE)) 

我得到的是每個月的服務數量。 但是這些服務我已經超過了100. 動態CASE WHEN有可能嗎?獲取所有服務以及該月的每個服務退貨編號。還應該在服務的AS名稱後面寫我。 另一個選擇是我手動編寫這100個服務,所以我只是想知道? 謝謝

+0

你使用了哪個數據庫?動態SQL是一個選項嗎? –

+0

請接受對您而言正確的答案。謝謝。 –

回答

1
select 
    service, 
    monthname (timestamp_iso(STATUSDATE)), 
    count (*)    
from 
    INCIDENT 
where 
    service in ('ADSL','IPTV','VOIP') 
group by 
    monthname(timestamp_iso(STATUSDATE)), 
    service 

我認爲這讓你接近你想要的。

+1

在這個查詢中,每個服務都將成爲一排,我想他希望爲每個服務獲得一列。 –

+0

當然,但我認爲他只是想要數據,如果你從左到右或上下切片......他想看的數據就在那裏。 –

+0

你可能想看看這篇文章如何樞軸轉..如果你真的想... http://stackoverflow.com/questions/24470/sql-server-pivot-examples –

3

SQL中不能有動態數量的列。

您可以編寫寫入要執行的SQL(動態SQL)的代碼(使用SQL或其他語言),但可能會變得混亂。 WSo中,生成的SQL查詢適用於固定數量的列,但是每次運行時都會有更改SQL查詢的代碼。

適合您的需求,不需要重新編碼的動態標準的關係數據庫模型,是標準化的結果...

SELECT 
    monthname (timestamp_iso(STATUSDATE)), 
    service, 
    COUNT(*) AS count_service 
FROM 
    incident 
GROUP BY 
    monthname(timestamp_iso(STATUSDATE)), 
    service 

那麼問題就變成:你真的需要一個pivotted結果集,當你不知道你會得到多少列?

+0

或者,如果它總是相同的100,並且您只是想節省時間輸入...將100個值複製到EXCEL中,然後使用它們爲您構建案例語句。然後將它們複製回SQL。 – MatBailie

+0

好的,謝謝...現在我已經超過了100個,所以我會寫它們,但是可能將來他們會添加一些更多的服務,所以我希望SQL代碼能夠自動代替它,而不是在代碼中添加,但是可以。你能否澄清我的旋轉結果集是什麼?因爲我不確定那是否是我想要的。你是對的我想有不知何故動態數列 – Dejan

+0

@Dejan - 規範化的結果是根據我的答案。透視結果是根據你的問題。它只是意味着採取行並使其成列。最重要的是它更加人性化。不利的一面是它不太適合SQL。 – MatBailie

2

如果你想做到這一點,在編程語言,你可以select DISTINCT service和構建查詢

例如,在C#

string SQL = "select monthname (timestamp_iso(STATUSDATE))" 

List<string> Columns = new List<string>(); 
foreach(string service in Services) 
{ 
    Columns.Add(" count (case when service='"+service+"' then 1 end) as "+service); 
} 

SQL +="," + String.Join(",",Columns.ToArray()); 
SQL += " from INCIDENT group by monthname(timestamp_iso(STATUSDATE))"; 

db.Query(SQL); 

在Javascript:

var SQL = "select monthname (timestamp_iso(STATUSDATE))"; 

var Columns = new Array(); 
foreach(string service in Services) 
{ 
    Columns.push(" count (case when service='"+service+"' then 1 end) as "+service); 
} 

SQL +="," + Columns.Join(','); 
SQL += " from INCIDENT group by monthname(timestamp_iso(STATUSDATE))"; 

db.Query(SQL); 

其他方式如果您使用oracle,您可以嘗試編寫PL/SQL來選擇列,並動態構建您的查詢,然後使用EXECUTE IMMEDIATE Statement

+0

請注意,「服務」值不是人爲生成的。或者你使用參數化查詢。 (使用動態數量的參數)。 – MatBailie

+0

是的,我先說,構建查詢.. –

+0

什麼之前選擇與DISTINC的服務,如果任何該列中的值包含'''? – MatBailie