2013-05-14 49 views
5

Nếu tôi có một bảng nhưChỉ chọn giá trị khác biệt từ hai cột từ một bảng

1 A 

1 B 

1 A 

1 B 

2 C 

2 C 

Và tôi muốn chọn khác biệt với hai cột vì vậy mà tôi sẽ nhận được

1 

2 

A 

B 

C 

thế nào tôi có thể từ truy vấn của mình không? Là cách duy nhất để nối các cột và quấn chúng xung quanh một toán tử hàm riêng biệt?

Trả lời

6

Bạn có thể sử dụng một union để tạo ra một bảng của tất cả các giá trị từ cả hai cột:

select col1 as BothColumns 
from YourTable 
union 
select col2 
from YourTable 

Không giống như union all, union loại bỏ bản sao, ngay cả khi họ xuất phát từ cùng một bên của union.

+1

@Luv: Các bên ngoài 'distinct' sẽ chăm sóc loại bỏ các bản sao. Không sử dụng buộc một thao tác sắp xếp nhiều hơn một lần. – Andomar

+0

Nó làm việc cho tôi ... Ngoài ra tôi muốn biết nếu tôi có nhiều hơn hai cột (Nói 5 cột) .... 5 truy vấn với công đoàn tất cả đang làm việc, nhưng là có bất kỳ phương pháp tối ưu hóa để làm điều đó .. hoặc Tôi phải làm bằng cách đề cập đến 5 truy vấn cho 5 cột – usr021986

+1

@Andomar: Kế hoạch truy vấn giống nhau nếu chúng ta xóa truy vấn riêng biệt bên ngoài và chỉ sử dụng 'union' trong truy vấn bên trong. Tôi không thể thấy hai loại. –

2

Vui lòng thử:

Select Col1 from YourTable 
union 
Select Col2 from YourTable 

UNION loại bỏ dữ liệu trùng nhau (trong đó tất cả các cột trong các kết quả đều giống nhau), UNION ALL không. Vui lòng kiểm tra What is the difference between UNION and UNION ALL

Đối với nhiều cột, bạn có thể sử dụng UNPIVOT.

SELECT distinct DistValues 
FROM 
    (SELECT Col1, Col2, Col3 
    FROM YourTable) p 
UNPIVOT 
    (DistValues FOR Dist IN 
     (Col1, Col2, Col3) 
)AS unpvt; 
+2

Sử dụng 'khác biệt' là không cần thiết trong giải pháp đầu tiên. –

+1

Có, U r chính xác. – TechDo

1

Hãy thử điều này một -

DECLARE @temp TABLE 
(
     Col1 INT 
    , Col2 NVARCHAR(50) 
) 

INSERT INTO @temp (Col1, Col2) 
VALUES (1, 'ab5defg'), (2, 'ae4eii') 

SELECT disword = (
    SELECT DISTINCT dt.ch 
    FROM (
     SELECT ch = SUBSTRING(t.mtxt, n.number + 1, 1) 
     FROM [master].dbo.spt_values n 
     CROSS JOIN (
      SELECT mtxt = (
       SELECT CAST(Col1 AS VARCHAR(10)) + Col2 
       FROM @temp 
      FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)' 
      ) 
     ) t 
     WHERE [type] = N'p' 
     AND number <= LEN(mtxt) - 1 
    ) dt 
    FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)' 
) 

Hoặc thử này -

DECLARE @temp TABLE 
(
    a CHAR(1), b CHAR(1) 
) 

INSERT INTO @temp (a, b) 
VALUES 
    ('1', 'A'), ('1', 'B'), ('1', 'A'), 
    ('1', 'B'), ('2', 'C'), ('2', 'C') 

SELECT a 
FROM @temp 

UNION 

SELECT b 
FROM @temp 
+0

Đối với nhiều cột (varchar (...)) thích hợp sử dụng XML (xem ví dụ đầu tiên) - Col1 + Col2 + ... – Devart

+2

Tôi không thể nói rằng câu trả lời này là ấn tượng - thậm chí đáng sợ - bởi sự phức tạp không cần thiết của nó. –

1

Bởi vì những gì bạn muốn chọn là ở các cột khác nhau, bạn có thể sử dụng đoàn như dưới đây:

select distinct tarCol from 
(select distinct column1 as tarCol from table 
union 
select distinct column2 from table) as tarTab 
2

SQL Fiddle

Tại sao thậm chí khác biệt trong Liên minh, hãy thử này:

select cast(id as char(1)) from test 
union 
select val from test 
+0

Không upvote này sớm hơn vì lạ 'cast', nhưng bạn là đúng về' union' – Andomar

0

Bạn có thể sử dụng như thế này để có được nhiều cột riêng biệt đánh giá cao

(SELECT DISTINCT `enodeb` as res, 
       "enodeb" as columnname 
FROM `raw_metrics`) 
UNION 
(SELECT DISTINCT `interval` as res, 
     "interval" as columnname 
FROM `raw_metrics`) 
Các vấn đề liên quan