[英]Select distinct values from multiple columns in same table
我正在嘗試構建一個 SQL 語句,該語句從位於同一個表中的多個列返回唯一的非空值。
SELECT distinct tbl_data.code_1 FROM tbl_data
WHERE tbl_data.code_1 is not null
UNION
SELECT tbl_data.code_2 FROM tbl_data
WHERE tbl_data.code_2 is not null;
比如tbl_data如下:
id code_1 code_2
--- -------- ----------
1 AB BC
2 BC
3 DE EF
4 BC
對於上表,SQL 查詢應返回兩列中所有唯一的非空值,即:AB、BC、DE、EF。
我對 SQL 相當陌生。 我上面的語句有效,但是有沒有更簡潔的方法來編寫這個 SQL 語句,因為這些列來自同一個表?
最好在您的問題中包含代碼,而不是含糊不清的文本數據,以便我們都使用相同的數據。 這是我假設的示例架構和數據:
CREATE TABLE tbl_data (
id INT NOT NULL,
code_1 CHAR(2),
code_2 CHAR(2)
);
INSERT INTO tbl_data (
id,
code_1,
code_2
)
VALUES
(1, 'AB', 'BC'),
(2, 'BC', NULL),
(3, 'DE', 'EF'),
(4, NULL, 'BC');
正如Blorgbeard評論的那樣,解決方案中的DISTINCT
子句是不必要的,因為UNION
運算符消除了重復的行。 有一個不消除重復的UNION ALL
運算符,但它在這里不合適。
在沒有DISTINCT
子句的情況下重寫您的查詢是這個問題的一個很好的解決方案:
SELECT code_1
FROM tbl_data
WHERE code_1 IS NOT NULL
UNION
SELECT code_2
FROM tbl_data
WHERE code_2 IS NOT NULL;
兩列在同一個表中並不重要。 即使列在不同的表中,解決方案也是相同的。
如果您不喜歡兩次指定相同過濾器子句的冗余,您可以在過濾之前將聯合查詢封裝在虛擬表中:
SELECT code
FROM (
SELECT code_1
FROM tbl_data
UNION
SELECT code_2
FROM tbl_data
) AS DistinctCodes (code)
WHERE code IS NOT NULL;
我發現第二個的語法更難看,但它在邏輯上更簡潔。 但是哪一個表現更好呢?
我創建了一個sqlfiddle ,它演示了 SQL Server 2005 的查詢優化器為兩個不同的查詢生成相同的執行計划:
如果 SQL Server 為兩個查詢生成相同的執行計划,那么它們實際上和邏輯上是等效的。
將上述內容與您問題中查詢的執行計划進行比較:
DISTINCT
子句使 SQL Server 2005 執行冗余排序操作,因為查詢優化器不知道在第一個查詢中被DISTINCT
過濾掉的任何重復項無論如何都會被UNION
過濾掉。
此查詢在邏輯上與其他兩個查詢等效,但冗余操作使其效率較低。 在大型數據集上,我希望您的查詢返回結果集所需的時間比此處的兩個更長。 不要相信我的話; 在您自己的環境中進行實驗以確保!
嘗試像SubQuery
這樣的東西:
SELECT derivedtable.NewColumn
FROM
(
SELECT code_1 as NewColumn FROM tbl_data
UNION
SELECT code_2 as NewColumn FROM tbl_data
) derivedtable
WHERE derivedtable.NewColumn IS NOT NULL
UNION
已經從組合查詢中返回DISTINCT值。
如果您有兩個以上的列,請嘗試此操作:
CREATE TABLE #temptable (Name1 VARCHAR(25),Name2 VARCHAR(25))
INSERT INTO #temptable(Name1, Name2)
VALUES('JON', 'Harry'), ('JON', 'JON'), ('Sam','harry')
SELECT t.Name1+','+t.Name2 Names INTO #t FROM #temptable AS tSELECT DISTINCT ss.value FROM #t AS t
CROSS APPLY STRING_SPLIT(T.Names,',') AS ss
聯合適用於所需行數據在類型、值等方面相似的任何地方。 無論您在同一個表中還是另一個表中有列都可以檢索,因為結果將保持不變(在上述答案之一中已經提到盡管)。
由於您不想要重復項,因此使用 UNION ALL 毫無意義,並且使用 distinct 完全沒有必要,因為 union 提供了不同的數據
可以創建視圖將是最佳選擇,因為視圖是表的虛擬表示。 然后可以在創建的視圖上整齊地進行修改
Create VIEW getData AS
(
SELECT distinct tbl_data.code_1
FROM tbl_data
WHERE tbl_data.code_1 is not null
UNION
SELECT tbl_data.code_2
FROM tbl_data
WHERE tbl_data.code_2 is not null
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.