Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 уникальные записи по всем столбцам в одной таблице  [new]
skais675
Member

Откуда:
Сообщений: 76
Есть таблица test:
a b c
1 1 1
2 1 3
2 2 4
3 3 5
1 3 4
1 2 4
1 1 1
1 4 6

Мне нужно получить новую таблицу test2, но чтоб в ее столбцах были только уникальные записи соответствующего столбца
Вот такой результат должен быть в test2:
a b c
1 1 1
2 2 3
3 3 4
null 4 5
null null 6

как вы видите никакой взаимосвязи в строках между столюцами нет просто уникальные записи.
Это нужно для того чтобы в последующем можно было вытащить уникальные записи по каждому столбцу из test.
Так как test - будет очень большой больше 1 000 000 записей, а уникальных десятки - хочется создать test2 - с десятками записей и работать потом с ней. Просто test и test2 имеют больше 20 столбцов и не хочется в приложение тянуть 20 таблиц с уникальными записями, тем более структура может меняться, а так все будет универсально.
26 сен 16, 08:58    [19707150]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
iljy
Member

Откуда:
Сообщений: 8711
skais675,

а нафига, собственно, понадобилось собирать никак не связанные между собой поля в строки? Выдайте списком уникальные значения поля а, потом - поля b, далее по индукции. DISTINCT вам в помощь.
26 сен 16, 13:29    [19708440]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
skais675
Member

Откуда:
Сообщений: 76
iljy, В том то и дело. Что если этих полей много к примеру 50.
А в приложение зачем мне тянуть 50 таблиц. А так я потянул одну таблицу а в C# можно по полю получить DISTICT любого столбца, просто все в цикле отрабатывает, а так нужно все жестко привязывать к примеру у меня 50 combobox и что теперь превязывать 50 таблиц? Не программно это, а рутинно.
26 сен 16, 13:39    [19708505]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
skais675,

звучит всё это глупо, как по мне, но думаю решение

SELECT DISTINCT 
	a as [Value],
	'a'as [Param]
FROM main
UNION ALL
SELECT DISTINCT 
	b as [Value],
	'b'as [Param]
FROM main
UNION ALL
SELECT DISTINCT 
	c as [Value],
	'c'as [Param]
FROM main

а в клиенте забираете для своих объектов
26 сен 16, 14:00    [19708625]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
982183
Member

Откуда: VL
Сообщений: 3357
Несомненно это выход.
Использовать можно.
26 сен 16, 14:34    [19708791]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
iljy
Member

Откуда:
Сообщений: 8711
982183
Несомненно это выход.
Использовать можно.


Именно. Для случая 50 полей подобный запрос легко генерится программно.
26 сен 16, 16:52    [19709704]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
Т-Миронов
Member

Откуда:
Сообщений: 3216
DECLARE @myTable TABLE
(
  a int, 
  b int,
  c int
)

INSERT INTo @myTable values (1,1,1)
INSERT INTo @myTable values (2,1,3)
INSERT INTo @myTable values (2,2,4)
INSERT INTo @myTable values (3,3,5)
INSERT INTo @myTable values (1,3,4)
INSERT INTo @myTable values (1,2,4)
INSERT INTo @myTable values (1,1, 1)
INSERT INTo @myTable values (1,4, 6)

SELECT ROW_NUMBER() OVER (ORDER BY a) id, a INTO #At from (SELECT DISTINCT a FROM @myTable) at
SELECT ROW_NUMBER() OVER (ORDER BY b) id, b INTO #Bt from (SELECT DISTINCT b FROM @myTable) bt
SELECT ROW_NUMBER() OVER (ORDER BY c) id, c INTO #Ct from (SELECT DISTINCT c FROM @myTable) ct

SELECT a,b,c FROM 
(SELECT DISTINCT id FROM #At
UNION SELECT id FROM #Bt
UNION SELECT id FROM #Ct
Group BY id) ids 
LEFT JOIN #At on ids.id = #at.id 
LEFT JOIN #Bt on ids.id = #Bt.id 
LEFT JOIN #Ct on ids.id = #Ct.id 

DROP table #At
DROP table #Bt
DROP table #Ct
26 сен 16, 17:21    [19709921]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
iljy
Member

Откуда:
Сообщений: 8711
Т-Миронов,

во-первых - можно проще
SELECT a,b,c FROM 
#At full JOIN #Bt on #At.id = #Bt.id 
    full JOIN #Ct on isnull(#At.id, #Bt.id) = #Ct.id 

, а во-вторых - остается вопрос "нафига". Чем такое представление с точки зрения конечного ПО выгоднее узкой таблицы?
26 сен 16, 17:27    [19709961]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
Т-Миронов
Member

Откуда:
Сообщений: 3216
iljy,

Там конкретная формулировка.
Для себя интерсно. Давно не писал t-sql.
26 сен 16, 18:25    [19710375]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
982183
Member

Откуда: VL
Сообщений: 3357
iljy
, а во-вторых - остается вопрос "нафига". Чем такое представление с точки зрения конечного ПО выгоднее узкой таблицы?

Из "любви к искусству"
Красиво же сделали.
27 сен 16, 02:29    [19711536]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
iljy
Member

Откуда:
Сообщений: 8711
982183,

можно и элегантнее

DECLARE @myTable TABLE
(
  a int, 
  b int,
  c int
)

INSERT INTo @myTable values (1,1,1)
INSERT INTo @myTable values (2,1,3)
INSERT INTo @myTable values (2,2,4)
INSERT INTo @myTable values (3,3,5)
INSERT INTo @myTable values (1,3,4)
INSERT INTo @myTable values (1,2,4)
INSERT INTo @myTable values (1,1, 1)
INSERT INTo @myTable values (1,4, 6)

select a,b,c
from (
	SELECT DENSE_RANK() OVER (ORDER BY a) id, a v, 'a' n from @myTable union all	
	SELECT DENSE_RANK() OVER (ORDER BY b) id, b v, 'b' n from @myTable union all
	SELECT DENSE_RANK() OVER (ORDER BY c) id, c v, 'c' n from @myTable
) t pivot (max(v) for n in (a,b,c)) p

, поиск по форуму даст вам еще пяток вариантов. Но не вся красота одинаково полезна, с точки зрения задачи такой запрос в общем случае сложнее генерировать, он тяжелее для сервера и его сложнее разбирать на клиенте: придется руками в цикле отсеивать пустые значения.
27 сен 16, 07:32    [19711611]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
982183
Member

Откуда: VL
Сообщений: 3357
Не, LEFT JOIN с группировкой по id, равному recno, намного понятнее.
А тут, если честно, сразу не врубился.
27 сен 16, 08:18    [19711642]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
skais675
Member

Откуда:
Сообщений: 76
Спасибо за все ответы!!!
Если уж копнуть глубже - можно как-то сделать автоматически на 50 полей к примеру, а то запрос получается на каждое поле приходится писать в ручную (не проблема но неприятно).
Столько вопросов - отвечаю:
Это нужно чтобы я в одной таблице вытащил все уникальные значения по 50 полям, а не тащил 50 таблиц с уникальными полями. А далее в приложении есть функция или фильтр без null и все. А то как-то некрасиво тянуть в приложение и создавать там кучу таблиц - не по программистки это на мой взгляд как-то.
Самое главное - что Вы мне показали - что решения есть - за это спасибо!!!
Хотелось бы еще чтоб запрос был универсальнее, то есть его бы не пришлось переписывать или дописывать при изменении количества полей.
28 сен 16, 09:14    [19716565]     Ответить | Цитировать Сообщить модератору
 Re: уникальные записи по всем столбцам в одной таблице  [new]
iljy
Member

Откуда:
Сообщений: 8711
skais675,

+ можно
use tempdb
begin tran

-- Таблица для опытов

declare @sql varchar(max) =
(select ', CHECKSUM(NEWID()) % (10 + ' + CAST(number as varchar) + '%10) f' + CAST(number as varchar)
from master..spt_values
where type = 'P' and number between 1 and 50
order by number
for xml path(''))

set @sql = 'select top(1000) identity(int) id' + @sql + ' into ttt from master..spt_values, master..spt_values v1'

--print @sql
exec(@sql)
go
-- Запрос 1

declare @sql varchar(max) = stuff((
select 'union all select DENSE_RANK() over(order	by ' + COLUMN_NAME + ') id, ''' + COLUMN_NAME + ''' n, ' + COLUMN_NAME + ' v from ttt '
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'ttt' and COLUMN_NAME != 'id'
for xml path('')), 1, 10, '')

declare @vars varchar(max) = stuff((
select ', ' + COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'ttt' and COLUMN_NAME != 'id'
for xml path('')), 1,2, '')

set @sql = 'select ' + @vars + ' from(' + @sql + ')t pivot(max(v) for n in (' + @vars + '))p'

print @sql
exec(@sql)

go
-- Запрос 2

declare @sql varchar(max) = stuff((
select 'union all select distinct ''' + COLUMN_NAME + ''' n, ' + COLUMN_NAME + ' v from ttt '
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'ttt' and COLUMN_NAME != 'id'
for xml path('')), 1, 10, '')

print @sql
exec(@sql)

go

drop table ttt
rollback
28 сен 16, 11:16    [19717185]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить