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

Откуда: Екатеринбург
Сообщений: 45
create table #A (P char(1))
insert into #A (P) values ('A')
insert into #A (P) values ('B')
insert into #A (P) values ('C')
insert into #A (P) values ('D')

create table #B (R char(1))
insert into #B (R) values ('1')
insert into #B (R) values ('2')
insert into #B (R) values ('3')
insert into #B (R) values ('4')


Select P + (select top 1 R from #B order by newid())
from #A


drop table #A
drop table #B

Мне нужно, чтобы в результате select вывел поле P из таблицы #A и к нему прибавил случайным образом поле R или таблицы #B.

Примерно пол года назад этот скрипт у меня работал, а сейчас второй select из таблицы #B выдаёт одно значение каждый раз, не выбирает его случайным порядком. Не понимаю, что не так.

т.е. сейчас я вижу картину

A3
B3
C3
D3



а должен видеть типа

A3
B1
C4
D2



select @@version
Microsoft SQL Server 2005 - 9.00.2047.00 (Intel X86)   Apr 14 2006 01:12:25   Copyright (c) 1988-2005 Microsoft Corporation  Express Edition with Advanced Services on Windows NT 5.2 (Build 3790: Service Pack 2) 
8 ноя 11, 10:50    [11562012]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка второй таблицы случайным способом, а раньше работала....  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
ИванПетрович
Примерно пол года назад этот скрипт у меня работал, а сейчас второй select из таблицы #B выдаёт одно значение каждый раз, не выбирает его случайным порядком. Не понимаю, что не так.
Это потому что коррелированный подзапрос никак не связан с внешним запросом.
Оптимизатор это сразу просекает, предполагает, что результат один и тот же для всех строк, и выполняет его один раз (для скорости).
Надо как-то связать запрос и подзапрос. Да так, чтобы оптимизатор не догадался!
8 ноя 11, 10:56    [11562045]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка второй таблицы случайным способом, а раньше работала....  [new]
ИванПетрович
Member

Откуда: Екатеринбург
Сообщений: 45
Пробую вот так, тоже не получается.
создал view с названием fnewid в которую поместил
select newid() as myrnd

и делал вот так запрос

Select P + (select top 1 R from #B order by fn.myrnd desc)
from #A, fnewid fn
order by fn.myrnd asc
8 ноя 11, 11:02    [11562077]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка второй таблицы случайным способом, а раньше работала....  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
ИванПетрович
Пробую вот так, тоже не получается.
создал view с названием fnewid в которую поместил
select newid() as myrnd

и делал вот так запрос

Select P + (select top 1 R from #B order by fn.myrnd desc)
from #A, fnewid fn
order by fn.myrnd asc
Внутри коррелированного подзапроса значение поля внешнего запроса - это просто константа.
Какой смысл по нему опорядочивать ORDER BYем?

Кроме того, VIEW в запросе ракрывается перед оптимизацией. Смысла в данном случае не видно.
Так не сработает?
SELECT P + (SELECT TOP(1) #B.R from #B LEFT JOIN #A A ON #B.R=A.P WHERE A.P=#A.P ORDER BY NEWID())
FROM #A;
8 ноя 11, 11:11    [11562149]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка второй таблицы случайным способом, а раньше работала....  [new]
aleks2
Guest
1. Засунуть подзапрос в скалярную функцию.
2. Объявить функцию недетерминированной.
8 ноя 11, 11:13    [11562167]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка второй таблицы случайным способом, а раньше работала....  [new]
aleks2
Guest
В качестве бредовой идеи:
Объявить в таблице #B вычисляемое поле newid().
8 ноя 11, 11:15    [11562188]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка второй таблицы случайным способом, а раньше работала....  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381

у меня и так сработало:
Select P + (select top 1 R from #B order by P, newid())
from #A
без особых гарантий, правда.

Posted via ActualForum NNTP Server 1.4

8 ноя 11, 11:19    [11562233]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка второй таблицы случайным способом, а раньше работала....  [new]
ИванПетрович
Member

Откуда: Екатеринбург
Сообщений: 45
SELECT P + (SELECT TOP(1) #B.R from #B LEFT JOIN #A A ON A.P=#A.P WHERE A.P=#A.P ORDER BY NEWID())
FROM #A

Долго вникал в условие join и переделал на join A.P=#A.P и заработало.

Этот вариант тоже работает
Select P + (select top 1 R from #B order by P, newid())
from #A


проблема в том, что я не могу использовать newid() так как это запрос у меня выполняется в функции. Для этого я выносил newid() во view.

Как правильно сделать этот запрос в функции ?
8 ноя 11, 16:15    [11564753]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка второй таблицы случайным способом, а раньше работала....  [new]
invm
Member

Откуда: Москва
Сообщений: 9827
use tempdb;
go
create table dbo.A (P char(1))
insert into dbo.A (P) values ('A')
insert into dbo.A (P) values ('B')
insert into dbo.A (P) values ('C')
insert into dbo.A (P) values ('D')

create table dbo.B (R char(1))
insert into dbo.B (R) values ('1')
insert into dbo.B (R) values ('2')
insert into dbo.B (R) values ('3')
insert into dbo.B (R) values ('4')
go
create view dbo.vNewid
as
select newid() as [guid];
go
create function dbo.fnAB()
returns table
as
return
(
 select
  a.P + t.R as PR
 from
  dbo.A a cross apply
  (
   select top (1)
    b.R
   from
    dbo.B b cross join
    dbo.vNewid x
   order by
    a.P, x.[guid]
  ) t
);
go
select * from dbo.fnAB();
select * from dbo.fnAB();
select * from dbo.fnAB();
select * from dbo.fnAB();
go
drop function dbo.fnAB;
drop view dbo.vNewid;
drop table dbo.A;
drop table dbo.B;
go
8 ноя 11, 17:25    [11565363]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка второй таблицы случайным способом, а раньше работала....  [new]
ИванПетрович
Member

Откуда: Екатеринбург
Сообщений: 45
invm,


спасибо, всё получилось.
8 ноя 11, 19:27    [11566022]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить