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

Откуда: Minsk Power Station
Сообщений: 508
Привет!
Как можно установить отбор необходимого количества записей в случае если используется UNION ALL?
Каркас такой:
SELECT TOP 50 ID, Name FROM T1 INNER JOIN T2 ON T1.ID = T2.ID
UNION ALL
SELECT ID, Name FROM T1 INNER JOIN T3 ON T1.ID = T3.ID
ORDER BY ID DESC
в результате возвращает 50 записей по первому запросу и все которые во втором селекте.
Пробовал делать:
SELECT TOP 50 ID, Name FROM T1 INNER JOIN T2 ON T1.ID = T2.ID
UNION ALL
SELECT TOP 50 ID, Name FROM T1 INNER JOIN T3 ON T1.ID = T3.ID
ORDER BY ID DESC

тогда выдаёт 100 записей и самое печальное, что половина ID не участвует в выдаче, т.е. идёт так:
ID, Name
5537, Макет1
5536, Макет4
5430, Макет1
5439, Макет7
5025, Макет8
...
т.е. куда-то выпадают ID

Как мне отобрать 50 записей из соединённого запроса?
28 апр 13, 18:17    [14240945]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31432
palladin600
Как можно установить отбор необходимого количества записей в случае если используется UNION ALL?
SELECT TOP 50 *
FROM (
    SELECT TOP 50 ID, Name FROM T1 INNER JOIN T2 ON T1.ID = T2.ID
    UNION ALL
    SELECT ID, Name FROM T1 INNER JOIN T3 ON T1.ID = T3.ID
) t
ORDER BY ID DESC
28 апр 13, 18:37    [14240983]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31432
palladin600
Как можно установить отбор необходимого количества записей в случае если используется UNION ALL?
SELECT TOP 50 *
FROM (
    SELECT ID, Name FROM T1 INNER JOIN T2 ON T1.ID = T2.ID
    UNION ALL
    SELECT ID, Name FROM T1 INNER JOIN T3 ON T1.ID = T3.ID
) t
ORDER BY ID DESC
28 апр 13, 18:37    [14240984]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
palladin600
Member

Откуда: Minsk Power Station
Сообщений: 508
Big thx! Alles gut!
28 апр 13, 19:36    [14241115]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
palladin600
Member

Откуда: Minsk Power Station
Сообщений: 508
А можно получить конкретный диапазон данных?
Т.е. не TOP 50, а например, из запроса записи с 50-ой по 100-ую.
Как-бы пейджинг...
28 апр 13, 19:43    [14241146]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
palladin600
А можно получить конкретный диапазон данных?
Т.е. не TOP 50, а например, из запроса записи с 50-ой по 100-ую.
Как-бы пейджинг...
Раз версия не указана, то допустим, что SQL 2012
ORDER BY ID DESC OFFSET 49 ROWS FETCH NEXT 50 ROWS ONLY
28 апр 13, 20:05    [14241211]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
palladin600
Member

Откуда: Minsk Power Station
Сообщений: 508
iap
Раз версия не указана, то допустим, что SQL 2012
ORDER BY ID DESC OFFSET 49 ROWS FETCH NEXT 50 ROWS ONLY


Крутейшая подсказка. Спасибо.
Получается тогда и ТОР не нужен.
28 апр 13, 21:08    [14241457]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
palladin600
iap
Раз версия не указана, то допустим, что SQL 2012
ORDER BY ID DESC OFFSET 49 ROWS FETCH NEXT 50 ROWS ONLY


Крутейшая подсказка. Спасибо.
Получается тогда и ТОР не нужен.
Для 2005-ого и 2008-ого тоже можно без TOP.
Надо пронумеровать ROW_NUMBER()ом и ограничить диапазоном в WHERE
28 апр 13, 21:39    [14241523]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
И вот ещё что.
Тут есть FAQ по этому поводу
28 апр 13, 21:48    [14241548]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
iap, а так работает?
	SELECT TOP(50) * FROM T
	ORDER BY ID ASC
UNION ALL
	SELECT TOP(50) * FROM T
	ORDER BY ID DESC
Нет?
Я так и знал что логики никакой.
28 апр 13, 21:56    [14241566]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
Mnior
iap, а так работает?
	SELECT TOP(50) * FROM T
	ORDER BY ID ASC
UNION ALL
	SELECT TOP(50) * FROM T
	ORDER BY ID DESC
Нет?
Я так и знал что логики никакой.
Я на первый-то вопрос не отвечал,
а автору требовалось 50 строчек всего, а не от каждого SELECT в UNION.

C ORDER BY в UNION существует тонкость - ведь упорядочивается весь датасет, а не каждый SELECT.
И сервер не всегда заморачивается на TOP,
хотя встречались такие случаи (завтра поищу тут на форуме, если надо).
Гарантированно можно обойти так:
SELECT * FROM
(SELECT TOP(50) * FROM T
	ORDER BY object_id ASC)T
UNION ALL
SELECT * FROM
(SELECT TOP(50) * FROM T
	ORDER BY object_id ASC)T
28 апр 13, 22:22    [14241646]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
object_id оставил, извините! (Это я на sys.objects проверял на всякий случай). Имел в виду это:
SELECT * FROM
(SELECT TOP(50) * FROM T
	ORDER BY ID ASC)T
UNION ALL
SELECT * FROM
(SELECT TOP(50) * FROM T
	ORDER BY ID ASC)T
28 апр 13, 22:25    [14241650]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
palladin600
Member

Откуда: Minsk Power Station
Сообщений: 508
да, блин, с UNION ALL оффсет не работает.

может есть смысл избавится от UNION ALL?
но как это сделать тогда, если не известно с какой таблицей используется связь для каждой записи?
28 апр 13, 22:42    [14241678]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31432
palladin600
да, блин, с UNION ALL оффсет не работает.
А ошибка какая?
28 апр 13, 23:24    [14241747]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
palladin600
Member

Откуда: Minsk Power Station
Сообщений: 508
alexeyvg
palladin600
да, блин, с UNION ALL оффсет не работает.
А ошибка какая?

ошибка - то, что из первого селекта отдаются данные, а со второго - нет, по-крайней мере в первых 50 записей отбора
28 апр 13, 23:36    [14241771]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
iap
Гарантированно можно обойти так:
	SELECT * FROM (SELECT TOP(50) * FROM T ORDER BY object_id ASC ) T
UNION ALL
	SELECT * FROM (SELECT TOP(50) * FROM T ORDER BY object_id DESC) T
Оно-то понятно, что обойти можно.
Проблема почему порядок и область действия операторов языка организованы именно таким способом?
ORDER BY к чему относится, к всему запросу? К каждому? Влияет ли он на TOP всех запросов? первого? последнего?

Почему нельзя перенести TOP ближе к оконным функциям и полностью отделить его от ORDER BY запроса?
Потому что этот фатальный недостаток обратно несовместим? Отчего же, пусть оба сосуществуют:
-- Старый синтаксис
SELECT Top(N [ PERCENT ] ) ... ORDER BY X 

-- Новый синтаксис
SELECT Top(N [ PERCENT ])OVER([ PARTITION BY G ] [ ORDER BY Y ]) ...
[ ORDER BY X ]
А то так получается, что и крылья есть, и хвост, а не летить.

PS: Незабываем проголосовать.
29 апр 13, 03:00    [14241984]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31432
palladin600
alexeyvg
пропущено...
А ошибка какая?

ошибка - то, что из первого селекта отдаются данные, а со второго - нет, по-крайней мере в первых 50 записей отбора
Наверное, в запросе ошибка?

А то я уж подумал, что OFFSET с UNION действительно запрещено использовать...
29 апр 13, 09:06    [14242160]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
iap
C ORDER BY в UNION существует тонкость - ведь упорядочивается весь датасет, а не каждый SELECT.
И сервер не всегда заморачивается на TOP,
хотя встречались такие случаи (завтра поищу тут на форуме, если надо).
scan direction + union all
29 апр 13, 09:24    [14242209]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
iap
scan direction + union all
Гы, буквально пару дней назад запускал оное и выдавало ошибку, сервер 2000ый.
29 апр 13, 09:33    [14242233]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10234
Блог
Mnior
iap
scan direction + union all
Гы, буквально пару дней назад запускал оное и выдавало ошибку, сервер 2000ый.

ага...2005 and UP
29 апр 13, 09:37    [14242259]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 2994
Knyazev Alexey
Mnior
пропущено...
Гы, буквально пару дней назад запускал оное и выдавало ошибку, сервер 2000ый.

ага...2005 and UP


Microsoft SQL Server  2000 - 8.00.2040 (Intel X86)   May 13 2005 18:33:17   Copyright (c) 1988-2003 Microsoft Corporation  Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2) 


все отработало

вот если не обарачивать, то тогда да ошибка и даже на 2008
29 апр 13, 10:01    [14242398]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10234
Блог
HandKot
все отработало

хм, если перечислять столбцы, то да...и в 2000-ом отработало...со * в 2000-м ругается

select @@version as version

declare @t table (id int identity)
insert into @t default values
insert into @t default values
insert into @t default values
insert into @t default values
insert into @t default values

select * from
(
select top 1 * from @t order by id
union all
select top 1 * from @t order by id desc
) t 


Msg 104, Level 15, State 1, Line 11
ORDER BY items must appear in the select list if the statement contains a UNION operator.
Msg 104, Level 15, State 1, Line 11
ORDER BY items must appear in the select list if the statement contains a UNION operator.


Microsoft SQL Server  2000 - 8.00.2301 (Intel X86) 
	Jan  6 2012 17:23:12 
	Copyright (c) 1988-2003 Microsoft Corporation
	Enterprise Edition on Windows NT 5.2 (Build 3790: Service Pack 2)
29 апр 13, 10:16    [14242504]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 2994
Knyazev Alexey
хм, если перечислять столбцы, то да...и в 2000-ом отработало...со * в 2000-м ругается

хм, но если заменить не именами а номером, то опять все нормально
select @@version as version

declare @t table (id int identity)
insert into @t default values
insert into @t default values
insert into @t default values
insert into @t default values
insert into @t default values

select * from
(
select top 1 * from @t order by 1
union all
select top 1 * from @t order by 1 desc
) t 


в общем, грабли какие-то
29 апр 13, 10:47    [14242732]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Блин, от я туплю.

declare @t table (id int identity)
insert into @t default values

select * from (
	select top 1 * from @t order by 1
union all
	select top 1 * from @t order by 1 desc
) t

IF Exists(
	select top 1 * from @t order by 1
union all
	select top 1 * from @t order by 1 desc
)	PRINT 'Work'
Всё логично, тут два совершенно разных синтаксиса.
Один для выражения (в подзапросах, представлениях), где ORDER BY сам по себе бессмыслен.
И другой для самого запроса в целом (выдача на клиент).

Но всё равно OVER понятнее и удобнее.
29 апр 13, 11:50    [14243210]     Ответить | Цитировать Сообщить модератору
 Re: Не получается установить SELECT TOP 50 для запроса с UNION ALL  [new]
palladin600
Member

Откуда: Minsk Power Station
Сообщений: 508
Так, ну блин, столько трений сторон...
Довольно трудно вникнуть. Можно попросить наглядный пример для моего случая, чтобы работал пейджинг из двух селектов?
29 апр 13, 16:31    [14245218]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить