[英]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
)
)
我認為合並兩個具有不同列數的選擇會返回錯誤。 如果我刪除最外面的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.