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

Откуда:
Сообщений: 7
Есть две таблички.

declare @mm table(k nvarchar(10) ,value int )
insert into @mm values('Кот1', 2)
insert into @mm values('Кот1', 4)
insert into @mm values('Кот3', 6)
insert into @mm values('Кот3', 8)
insert into @mm values('Кот5', 10)
insert into @mm values('Кот5', 12)


declare @fi table(k nvarchar(10) ,value int )
insert into @fi values('Кот1', 1)
insert into @fi values('Кот1', 3)
insert into @fi values('Кот5', 5)
insert into @fi values('Кот5', 7)

Нужно их объединить так:
Кот1 2 1
Кот1 4 3

Кот5 10 5
Кот5 12 7

или так:
Кот1 2 3
Кот1 4 1

Кот5 10 7
Кот5 12 5


То есть должны получится пары из колонок "value" так, что бы число из каждой таблицы участвовало только в одной паре.
Если делать просто Join то будет вот так:
Кот1 2 1
Кот1 2 3
Кот1 4 1
Кот1 4 3
Кот5 10 5
Кот5 10 7
Кот5 12 5
Кот5 12 7

Использовать нужно чистый SQL (T-SQL) без всяких наворотов MS SQL Server
21 янв 14, 11:11    [15445287]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
Glory
Member

Откуда:
Сообщений: 104751
revolution_rus
Использовать нужно чистый SQL (T-SQL) без всяких наворотов MS SQL Server

чистый TSQL - это уже "навороты MS SQL Server"
чистый SQL - это какой для вас ? ANSI SQL:1999, SQL:2003, SQL:2008, SQL:2011 ?
21 янв 14, 11:18    [15445326]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
qwerty112
Guest
revolution_rus,

делаешь 2-а запроса с
row_number() over (partition by k order by value) as rn

и потом JOIN их по k и rn

или row_number - это "наворот" ?
вдруг что, row_number можно эмулировать коррелированным подзапросом
21 янв 14, 11:19    [15445331]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
revolution_rus
Member

Откуда:
Сообщений: 7
Glory, ANSI SQL:1999
21 янв 14, 11:27    [15445393]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
Добрый Э - Эх
Guest
revolution_rus,

в чистом ANSI SQL 2002 есть такая фича, как JOIN PARTITIONED. Вот оно, наверное, натянулось бы на твою задачу. Но вот незадача - MS SQL Server ни какой из версий не поддерживает этот тип соединений.
21 янв 14, 11:29    [15445409]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
Glory
Member

Откуда:
Сообщений: 104751
revolution_rus
Glory, ANSI SQL:1999

Тогда придется нумеровать записи внутри групп через коррелированный подзапрос
21 янв 14, 11:29    [15445410]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
revolution_rus
Member

Откуда:
Сообщений: 7
qwerty112, вот так?

declare @mm table(k nvarchar(10) ,value int )
insert into @mm values('Кот1', 2)
insert into @mm values('Кот1', 4)
insert into @mm values('Кот3', 6)
insert into @mm values('Кот3', 8)
insert into @mm values('Кот5', 10)
insert into @mm values('Кот5', 12)


declare @fi table(k nvarchar(10) ,value int )
insert into @fi values('Кот1', 1)
insert into @fi values('Кот1', 3)
insert into @fi values('Кот5', 5)
insert into @fi values('Кот5', 7)


declare @t3 table(k nvarchar(10) ,value int )


select
mm.k,
mm.value,
fi.value
from
(
select
k,
value,
row_number() over (order by k desc) as r1
from
@mm
) mm

join
(
select
k,
value,
row_number() over (order by k desc) as r1
from
@fi
)

fi on mm.r1 = fi.r1 and mm.k = fi.k
21 янв 14, 11:30    [15445414]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
Glory
Member

Откуда:
Сообщений: 104751
revolution_rus
qwerty112, вот так?

В ANSI SQL:1999 нет оконных функций
21 янв 14, 11:30    [15445421]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34705
revolution_rus,

ну вот, уже и тут филиал кружка "напиши за меня запрос, хрен знает, какой, я и сам не знаю, что мне нужно".
21 янв 14, 11:50    [15445528]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
_djХомяГ
Guest
------как пронумеровать записи на "чистом  SQL" 
declare @mm table(k nvarchar(10) ,value int )
insert into @mm values('Кот1', 2)
insert into @mm values('Кот1', 4)
insert into @mm values('Кот3', 6)
insert into @mm values('Кот3', 8)
insert into @mm values('Кот5', 10)
insert into @mm values('Кот5', 12)

select m.*,(select count(*) from @mm m1 where m.k=m1.k and m1.value<=m.value) as ROWNUM
from @mm m

Далее осуществите аналогич маневр с другой таблицей а дальше по сказанному в топиках выше поджойните
21 янв 14, 12:53    [15445844]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
StarikNavy
Member

Откуда: Москва
Сообщений: 2414
revolution_rus,
и что тут из "реальной жизни"?
21 янв 14, 13:05    [15445934]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
Кот Матроскин
Member

Откуда: Москва
Сообщений: 8933
_djХомяГ,

Это будет работать до тех пор пока value уникальный (хотя бы в пределах k).

ТС
"задачка из жизни"="с собеседования"? :)
21 янв 14, 13:21    [15446077]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
_djХомяГ
Guest
Кот Матроскин
_djХомяГ,

Это будет работать до тех пор пока value уникальный (хотя бы в пределах k).


1 Автор ничего не гворил про это, а судя по приведенному заполнению таблиц значение уникально
2 На неуникальность есть и другие способы (к примеру таблица с identity полем)
Возвращение порядковых номеров строк в результирующем наборе
21 янв 14, 13:34    [15446181]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
select 
  m.k, 
  case n.n when 1 then m.vn else m.vx end v1, 
  case n.n when 1 then f.vn else f.vx end v2
from (select k, min(value)vn, max(value)vx from @mm group by k)m
join (select k, min(value)vn, max(value)vx from @fi group by k)f on f.k=m.k 
cross join(select 1 n union all select 2)n
21 янв 14, 13:58    [15446436]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
revolution_rus
Member

Откуда:
Сообщений: 7
Я придумал как сделать. Все работает отлично.
Вот код:

declare @mm table(k nvarchar(10) ,value int )
insert into @mm values('Кот3', 6)
insert into @mm values('Кот1', 4)
insert into @mm values('Кот5', 10)
insert into @mm values('Кот3', 8)
insert into @mm values('Кот1', 2)
insert into @mm values('Кот6', 14)
insert into @mm values('Кот5', 12)


declare @fi table(k nvarchar(10) ,value int )
insert into @fi values('Кот5', 5)
insert into @fi values('Кот6', 9)
insert into @fi values('Кот1', 1)
insert into @fi values('Кот5', 7)
insert into @fi values('Кот1', 3)

select
mm.k as [Key],
mm.value as mmValue,
fi.value

from
(
SELECT
mm.k,
mm.value,
ROW_NUMBER() OVER (PARTITION BY mm.k ORDER By mm.k, mm.value) as numberInGroup
FROM
@mm as mm
) as mm

left join
(
SELECT
fi.k,
fi.value,
ROW_NUMBER() OVER (PARTITION BY fi.k ORDER By fi.k, fi.value) as numberInGroup
FROM
@fi as fi

) as fi on( mm.k = fi.k and ( mm.numberInGroup = fi.numberInGroup or fi.numberInGroup is null ) )

К сообщению приложен файл (SQLQuery4.sql - 1002bytes) cкачать
21 янв 14, 13:58    [15446439]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
Glory
Member

Откуда:
Сообщений: 104751
revolution_rus
Я придумал как сделать. Все работает отлично.
Вот код:

Он же не на чистом SQL

И что будет, если в @fi будет еще insert into @fi values('Кот1', 5) ?

Сообщение было отредактировано: 21 янв 14, 14:01
21 янв 14, 14:00    [15446454]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
_djХомяГ
Guest
А ROW_NUMBER() это "чистый SQL" или "наворот"?
21 янв 14, 14:00    [15446465]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
revolution_rus
Member

Откуда:
Сообщений: 7
Кот Матроскин, нет=)
21 янв 14, 14:02    [15446480]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
revolution_rus
Member

Откуда:
Сообщений: 7
_djХомяГ, ТОже пришел к этой же идеи. Сделал немного по другом
21 янв 14, 14:04    [15446499]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
revolution_rus
Member

Откуда:
Сообщений: 7
Glory, По бизнес процессу такое не возможно. Кол-во в @fi и @mm всегда одно. Не может быть что в @mm 2 штуки а в @fi 3
21 янв 14, 14:19    [15446638]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
Glory
Member

Откуда:
Сообщений: 104751
revolution_rus
По бизнес процессу такое не возможно. Кол-во в @fi и @mm всегда одно.

А left join тогда зачем, если " такое не возможно" ?
Или там запятая пропущена ? такое не возможно - такое не, возможно
21 янв 14, 14:21    [15446658]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Glory
revolution_rus
qwerty112, вот так?

В ANSI SQL:1999 нет оконных функций
Ошибаетесь.
Именно в SQL1999 они и появились: http://savage.net.au/SQL/sql-2003-2.bnf.html

Но чистым, наверно, надо считать ANSI SQL-89?
21 янв 14, 15:06    [15447033]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
Glory
Member

Откуда:
Сообщений: 104751
iap
Именно в SQL1999 они и появились: http://savage.net.au/SQL/sql-2003-2.bnf.html

А ссылка на sql-2003
21 янв 14, 15:09    [15447052]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Glory
iap
Именно в SQL1999 они и появились: http://savage.net.au/SQL/sql-2003-2.bnf.html

А ссылка на sql-2003
Упс!!
Действительно!
Посыпаю голову пеплом.
Рассеянный я стал какой-то...

В SQL-1999 OVER() ещё не было
21 янв 14, 16:53    [15448035]     Ответить | Цитировать Сообщить модератору
 Re: SQL Головоломка из реальной жизни  [new]
foalfoot
Member

Откуда:
Сообщений: 2
revolution_rus,
все слишком заморочились на оконных функциях. Все проще:


SELECT COALESCE(m.k,f.k) Name,
m.value v1,
f.value v2
FROM @mm m
FULL JOIN @fi f ON (m.k=f.k)
WHERE m.value is NOT NULL AND f.value is NOT NULL
ORDER BY Name,v1,v2
21 янв 14, 18:31    [15448627]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить