2010-05-27 104 views
0

我意識到這是可能創造源碼內的交叉類,但是它可以動態地在運行時確定的相關類別/列,而不是硬編碼呢?動態創建SQLite的樞軸/交叉

考慮下面的例子,它可以變得相當乏味......

SELECT 
shop_id, 
sum(CASE WHEN product = 'Fiesta' THEN units END) as Fiesta, 
sum(CASE WHEN product = 'Focus' THEN units END) as Focus, 
sum(CASE WHEN product = 'Puma' THEN units END) as Puma, 
sum(units) AS total 

FROM sales 
GROUP BY shop_id 

我設法在之前stored proceedure爲此在SQLServer的,不知道有沒有什麼相同的。

回答

0

不,你不能這樣做,在SQLite的,因爲在SQLite的分析手段缺乏many usefull features較重的RDBMS可用。 Here是相應的票證,但它處於待定狀態。

+0

確定。感謝那。 如此怪異的東西,如MS Access有它,但它是如此棘手甚至可以在其它數據庫中的等價物。 – alj 2010-05-27 19:26:35

0

老問題,但無論如何,我僞造了這樣的事情在Ruby on Rails的。爲了我的目的,它運作良好。

def self.yearstats(attr) 
    # Determine number of columns 
    minyear = self.select("strftime('%Y', min(recorded_at)) AS minyear").first.minyear.to_i 
    maxyear = self.select("strftime('%Y', max(recorded_at)) AS maxyear").first.maxyear.to_i 
    # Stitch SQL query. Use explicit same column name to not confuse Rails' typecasting. 
    select_str = ["strftime('#{minyear}/%m/%d %H:%m', recorded_at) AS recorded_at"] 
    (minyear..maxyear).to_a.each do |y| 
     # avg because the table might have multiple rows per day 
     select_str += ["avg(case when strftime('%Y', recorded_at)='#{y}' then #{attr} end) AS value#{y}"] 
    end 
    self.select(select_str.join(",")).group("strftime('%m/%d', recorded_at)").all.collect {|row| 
     [row.recorded_at.utc.to_i*1000] + (minyear..maxyear).to_a.collect { |y| row.send("value#{y}") } 
    } 
    end 

注意,第一列我使用一個固定的第一年,使我的繪圖程序得到一個「真實」的日期,而不是日/月顯示器中使用的(假的)日期。這有點髒,但它適用於我的目的。 (改進仍然歡迎...)

而不是得到minyearmaxyear,你可能想做一個SELECT DISTINCT ..來獲得唯一的類別列表並適當地修改代碼。