簡體   English   中英

在SQLite中做數據透視表的最佳方法?

[英]Best way to do a pivot table in SQLite?

我正在使用C#和SQLite切片大量數據,並且我經常需要以數據透視表形式顯示數據。 通過使用C#從另一個查詢創建SQL命令,我可以輕松地使數據透視圖動態化,但是我仍然無法決定采用哪種方法進行數據透視圖本身,因此我想從經驗豐富的程序員那里聽到一些意見。我..

我想到了三種方法。 假設我們有一個名為tData的簡單表,該表具有三列:“行”代表該數據的行號,“ col”代表列號,“ val”代表值。

正統的方法是使用CASE表達式:

SELECT
      row,
      sum(CASE col WHEN 1 THEN val END) AS col1,
      sum(CASE col WHEN 2 THEN val END) AS col2,
      sum(CASE col WHEN 3 THEN val END) AS col3
FROM tData
GROUP BY row

但是,我在想,如果我放棄CASE語句並直接在值上使用邏輯表達式,並利用true == 1和false == 0的事實,可能會更快:

SELECT
      row,
      sum((col=1)*val) AS col1,
      sum((col=2)*val) AS col2,
      sum((col=3)*val) AS col3
FROM tData
GROUP BY row

我懷疑這種方法應該更快,因為CASE表達式應該有一些開銷,但是我不確定。

第三種方法稍微復雜一點:它使用JOIN進行透視:

SELECT
      rows.row,
      col1.valSum AS col1,
      col2.valSum AS col2,
      col3.valSum AS col3
FROM
    (SELECT row FROM tData GROUP BY row) AS rows
LEFT JOIN
    (SELECT row,sum(val) AS valSum FROM tData WHERE col=1 GROUP BY row) AS col1
    ON rows.row=col1.row
LEFT JOIN
    (SELECT row,sum(val) AS valSum FROM tData WHERE col=2 GROUP BY row) AS col2
    ON rows.row=col2.row
LEFT JOIN
    (SELECT row,sum(val) AS valSum FROM tData WHERE col=3 GROUP BY row) AS col3
    ON rows.row=col3.row

的確,那些JOIN的開銷很大,但是根據我在處理大型表時的有限經驗,SQL實現可以比每行自定義數據操作快得多的速度執行簡單的過濾器組和求和操作,並且彌補了這些開銷。 問題在於,這類SQL語句的生成更加復雜,因為每一列都出現在語句的兩個位置上-一次出現在fields子句中,一次出現在FROM子句中,而不是像前兩種方法那樣僅出現在fields子句中。 另外,我需要小心所有這些臨時表的名稱。

那么,有什么意見嗎?

我希望case語句方法的執行速度比對表進行的groupbys-joins更快,因為在問題列中有不同的值。 前者是CPU密集型,后者是磁盤密集型。 例如,如果要成為列標題的列值包含一周中的某一天,則您將有七個樞軸列和七個selects-groupbys。 那可能很昂貴; 這將取決於表的大小。

看起來您正在使用EAV設計,這有必要將行旋轉為列。 在適當的關系數據庫設計中,您不會使用EAV。 列就是列,您不需要旋轉。

就是說,我了解到,EAV有時不那么邪惡,當需要在數據庫中存儲一組“可擴展”屬性時,它是一種流行的設計。

取回數據的最有效方法是忘記執行SQL中的樞軸操作。 只需根據row給定值將屬性作為多行獲取:

SELECT row, col, val FROM tData WHERE row = ...

然后在您的C#應用​​程序中編寫代碼,以循環遍歷所得的多行結果集。 為每個不同的row創建一個新對象。 將對象的col字段設置為val 然后繼續獲取查詢結果的下一行。

這具有以下優點:

  • 該查詢易於編寫。 選擇列表中僅需命名三列,無需列別名。
  • 對於RDBMS執行該查詢是廉價的。 沒有GROUP BY ,沒有自我加入,等等。
  • 仍然支持EAV設計的可擴展優勢。 實際上,擴展起來更容易,因為在向數據添加新的邏輯列時,不必重寫SQL查詢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM