Primary-Key

如何在“SELECT … GROUP BY …”的結果中包含在功能上依賴於分組列的所有其他列?

  • September 16, 2014

我將這個問題基於一個玩具範例。

讓它成為表A

           A
-------------------------
U | V | W | X | Y |  Z
-------------------------
a | b | c | 1 | 6 | 8.3
a | b | c | 1 | 4 | 3.7
a | b | f | 3 | 4 | 2.6
a | b | f | 3 | 2 | 6.0
a | e | c | 1 | 0 | 3.5
a | e | c | 1 | 5 | 8.8
d | b | f | 1 | 0 | 3.5
d | b | f | 1 | 3 | 2.3
d | e | c | 2 | 6 | 2.2
d | e | c | 2 | 4 | 3.3
d | e | f | 0 | 7 | 5.0
d | e | f | 0 | 6 | 3.6

我可以通過按列、和B對 的行進行分組併計算每個組的 Z 列的平均值來生成第二個表。A``U``V``W

        B
-------------------
U | V | W | Z_avg
-------------------
a | b | c |  6.0
a | b | f |  4.3
a | e | c |  6.2
d | b | f |  2.9
d | e | c |  2.7
d | e | f |  4.3

用於此的 SQL 類似於

SELECT U, V, W, AVG(Z) AS Z_avg FROM A GROUP BY U, V, W;

U但我希望新表包含原始表中對分組列、V和有功能依賴的所有列W。在此範例中,有一個這樣的列,即 column X

換句話說,我想生成C如下所示的表格:

          C
-----------------------
U | V | W | X | Z_avg
-----------------------
a | b | c | 1 |  6.0
a | b | f | 3 |  4.3
a | e | c | 1 |  6.2
d | b | f | 1 |  2.9
d | e | c | 2 |  2.7
d | e | f | 0 |  4.3

所以這個問題有兩個部分,至少在概念上是這樣。

  1. 如何確定哪些列在功能上依賴於列UVW
  2. 生成表的 SQL 是什麼C

我知道如何實現可以回答 (1) 的(例如 Python)腳本,但它既乏味又緩慢。(基本上,對於每個候選列,在這種情況下X和,腳本將為列、和Y中的每個不同的值組合收集其所有值,然後,如果這些值組中的每一個都恰好具有一個元素,那麼該列在功能上與、和.)U``V``Z``U``V``Z

同樣,一旦我確定了功能相關的列,我可以通過(使用臨時表等等)最終得到類似C上面的表(因此,有效地解決(2))。

然而,我認為這項任務非常普遍,可能有標準的工具/技術來執行它。

假設您有一些列(例如xy在您的範例中),您不知道它們在功能上是否等效 - 並且這些列沒有任何NULL值(這會使事情複雜化),您可以使用:

SELECT 
   u, v, w,                    -- the grouping columns

   AVG(z) AS z_avg,            -- the non-functionally dependent

   CASE WHEN MIN(x) = MAX(x)   -- a possibly functionally dependent
     THEN MIN(x) ELSE NULL     -- column
   END AS x,

   CASE WHEN MIN(y) = MAX(y)   -- another one
     THEN MIN(y) ELSE NULL
   END AS y
FROM 
   a
GROUP BY 
   u, v, w ;

如果一列在功能上不依賴(與目前數據),它將具有至少 2 個不同的值,因此MINMAX將不同,結果將NULL在所有行中顯示為該列。然後,您可以將其從查詢中刪除。

引用自:https://dba.stackexchange.com/questions/76771