簡體   English   中英

將所有查詢與具有不同列數的查詢合並

[英]union all with queries that have a different number of columns

我遇到過一個情況,我期望返回錯誤的 sqlite 查詢實際上是成功的,我想知道是否有人可以指出為什么這個查詢是有效的。

CREATE TABLE test_table(
  k INTEGER,
  v INTEGER
);

INSERT INTO test_table( k, v ) VALUES( 4, 5 );

SELECT * FROM(
  SELECT * FROM(
    SELECT k, v FROM test_table WHERE 1 = 0
  )
  UNION ALL
  SELECT * FROM(
    SELECT rowid, k, v FROM test_table
  )
)

上面的sqlfiddle

我認為合並兩個具有不同列數的選擇會返回錯誤。 如果我刪除最外面的SELECT *然后我收到我期待的錯誤: SELECTs to the left and right of UNION ALL do not have the same number of result columns

答案似乎很簡單:是的,這是一個怪癖。 我想用一個簡短的例子來證明這一點。 但在此之前,讓我們查閱文檔

可以使用 UNION、UNION ALL、INTERSECT 或 EXCEPT 運算符將兩個或多個簡單的 SELECT 語句連接在一起形成復合 SELECT。 在復合 SELECT 中,所有構成的 SELECT 必須返回相同數量的結果列。

所以文檔說得很清楚,兩個SELECTs必須提供相同數量的列。 但是,正如您所說,最外面的SELECT奇怪地避免了這種“限制”。

示例 1

SELECT * FROM(
    SELECT k, v FROM test_table
  UNION ALL
    SELECT k, v,rowid FROM test_table
);

結果:

k|v
4|5
4|5

正如評論中指出的那樣,第三列rowid被簡單地省略了。

示例 2

我們只是交換兩個 select 語句的順序。

 SELECT * FROM(
    SELECT k, v, rowid FROM test_table
  UNION ALL
     SELECT k, v FROM test_table
  );

結果

k|v|rowid
4|5|1
4|5|

現在,sqlite 不會省略該列,而是添加一個空值。

結論

這使我得出結論,如果將 UNION ALL 作為子查詢處理,則 sqlite 只會以不同的方式處理UNION ALL

PS:如果你只是使用UNION它在任何情況下都會失敗。

UNION ALL 將返回額外列中包含空值的結果。

基本 UNION 將失敗,因為沒有 ALL 的 UNION 必須具有來自兩個表的相同數量的列。

所以:

SELECT column1, column2 FROM table a
UNION ALL 
SELECT column1, column2, column3 FROM table b

返回第 3 列中包含空值的 3 列。

和:

SELECT column1, column2 FROM table a
UNION 
SELECT column1, column2, column3 FROM table b

應該會失敗,因為列數不匹配。

總之,您可以向 UNION 添加一個空白列,以便您從每個表中選擇 3 列並且它仍然有效。

前任:

SELECT column1, column2, '' AS column3 FROM table a
UNION  
SELECT column1, column2, column3 FROM table b

如果您的第二個查詢的列數較少,您可以這樣做:

select col1, col2, col3, col4, col5
from table A

union all

select col1, col2, col3, col4, NULL as col5, 
from table B

除了NULL之外,還可以使用一些字符串常量 - 'KPI' as col5

暫無
暫無

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

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