动态地创建用于SQLite的枢轴/交叉类别(Dynamically create categorie

2019-10-22 08:08发布

我意识到这是可能创造源码中的交叉表,但有可能以动态确定在运行时,相关类别/列,而不是硬编码呢?

考虑下面的例子,它可以变得相当繁琐...

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

我设法在做这在SQLServer的存储proceedure之前,不知道有没有什么相同的。

Answer 1:

不,你不能这样做,在SQLite的,因为在SQLite的分析手段缺乏许多有用的功能在较重的RDBMS可用。 下面是相应的车票,但它是在挂起状态。



Answer 2:

老问题,但无论如何,我伪造了这样的事情在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 ..得到类别的唯一列表并适当地修改代码。



文章来源: Dynamically create categories for SQLite pivot/crosstab