2013-05-14 6 views
5

Если у меня есть таблица, такие какВыберите только различные значения из двух столбцов из таблицы

1 A 

1 B 

1 A 

1 B 

2 C 

2 C 

И я хочу, чтобы выбрать отличие от двух колонок, так что я хотел бы получить

1 

2 

A 

B 

C 

Как могу ли я ответить на запрос? Единственный способ объединить столбцы и обернуть их вокруг отдельного оператора функции?

ответ

6

Вы можете использовать union создать таблицу всех значений из обоего колонок:

select col1 as BothColumns 
from YourTable 
union 
select col2 
from YourTable 

В отличии от union all, union удаляет дубликаты, даже если они происходят из одной и той же стороны union.

+1

@Luv: Внешний 'distinct' позаботится удаления дубликатов. Нет необходимости использовать операцию сортировки более одного раза. – Andomar

+0

Это сработало для меня ... Также я хочу знать, есть ли у меня более двух столбцов (скажем 5 столбцов) .... 5 запросов с объединением все работает, но есть ли оптимизированный метод для этого ... или Я должен сделать, указав 5 запросов для 5 столбцов. – usr021986

+1

@Andomar: План запроса тот же, если мы удалим внешний отдельный запрос и просто используем 'union' во внутреннем запросе. Я не вижу двух видов. –

2

Пожалуйста, попробуйте:

Select Col1 from YourTable 
union 
Select Col2 from YourTable 

UNION удаляет дубликаты записей (где все столбцы в результатах одинаковы), UNION ALL не делает. Пожалуйста, проверьте What is the difference between UNION and UNION ALL

Для нескольких столбцов вы можете отправиться в UNPIVOT.

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

Использование 'distinct' не требуется в первом решении. –

+1

Да, U r правильно. – TechDo

1

Попробуйте один -

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)' 
) 

Или попробуйте это -

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

Для нескольких столбцов (varchar (...)) подходящее использование XML (см. Первый пример) - Col1 + Col2 + ... – Devart

+2

Я не могу воздержаться от того, чтобы сказать, что этот ответ впечатляет - даже пугает - его ненужной сложностью. –

1

Потому что вы хотите выбрать в разных колонках, вы можете использовать союз, как показано ниже:

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

SQL Fiddle

Почему даже отчетливый в Союзе, попробуйте следующее:

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

Не поднял это раньше из-за странного 'cast', но вы правы насчет' union' – Andomar

0

Вы можете использовать, как это, чтобы получить несколько отчетливое столбец значений

(SELECT DISTINCT `enodeb` as res, 
       "enodeb" as columnname 
FROM `raw_metrics`) 
UNION 
(SELECT DISTINCT `interval` as res, 
     "interval" as columnname 
FROM `raw_metrics`) 
Смежные вопросы