动态创建SQLite pivot / crosstab的类别

时间:2010-05-27 12:30:24

标签: sqlite pivot crosstab

我意识到可以在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中执行此操作,并想知道是否有相同的内容。

2 个答案:

答案 0 :(得分:0)

不,你不能在SQLite中这样做,因为SQLite中的分析意味着在较重的RDBMS中缺少many usefull featuresHere是相应的故障单,但它处于挂起状态。

答案 1 :(得分: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

请注意,对于第一列,我使用固定的第一年(假)日期,以便我的图表例程获得“真实”日期,而不仅仅是日/月显示。这有点脏,但它适用于我的目的。 (改进仍然受欢迎......)

您可能希望执行SELECT DISTINCT ..而不是获取minyearmaxyear,以获取唯一的类别列表并相应地修改代码。