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

Откуда:
Сообщений: 134
Всем привет.

Ребят помогите найти оптимальное решение.
Вот какая задача стоит... Есть выборка такого шаблона:
select one, two, else,
(select distinct fd.first_qtr_current 
		from SHELL_CORP_TEMPDATA_DETAIL as fd, SHELL_CORP_TEMPDATA_MASTER as fm 
		where fm.espkey = fd.parentid 
		and fd.paramname = d.paramname  
		and fm.status='approve' 
		and datename(year,fm.startdate) = (datename(year,m.startdate)-1)  
		and fd.ikeyfield2 = 2 
		and fm.qtrrun 
			= (select max(qtrrun) from SHELL_CORP_TEMPDATA_MASTER 
					where datename(year,startdate) = (datename(year,m.startdate)-1) ) ) as first_qtr_prev,
(select distinct fd.second_qtr_current 
		from SHELL_CORP_TEMPDATA_DETAIL as fd, SHELL_CORP_TEMPDATA_MASTER as fm 
		where fm.espkey = fd.parentid 
		and fd.paramname = d.paramname  
		and fm.status='approve' 
		and datename(year,fm.startdate) = (datename(year,m.startdate)-1)  
		and fd.ikeyfield2 = 2 
		and fm.qtrrun 
			= (select max(qtrrun) from SHELL_CORP_TEMPDATA_MASTER 
					where datename(year,startdate) = (datename(year,m.startdate)-1) ) ) as second_qtr_prev,
(select distinct fd.third_qtr_current 
		from SHELL_CORP_TEMPDATA_DETAIL as fd, SHELL_CORP_TEMPDATA_MASTER as fm 
		where fm.espkey = fd.parentid 
		and fd.paramname = d.paramname  
		and fm.status='approve' 
		and datename(year,fm.startdate) = (datename(year,m.startdate)-1)  
		and fd.ikeyfield2 = 2 
		and fm.qtrrun 
			= (select max(qtrrun) from SHELL_CORP_TEMPDATA_MASTER 
					where datename(year,startdate) = (datename(year,m.startdate)-1) ) ) as third_qtr_prev,
from SHELL_CORP_TEMPDATA_DETAIL as d, SHELL_CORP_TEMPDATA_MASTER as m 
	where m.espkey = d.parentid 
order by d.fieldorder ASC

как лучше оптимизировать вьюшку, убрав вот эти повторы
(select distinct fd.third_qtr_current 
		from SHELL_CORP_TEMPDATA_DETAIL as fd, SHELL_CORP_TEMPDATA_MASTER as fm 
		where fm.espkey = fd.parentid 
		and fd.paramname = d.paramname  
		and fm.status='approve' 
		and datename(year,fm.startdate) = (datename(year,m.startdate)-1)  
		and fd.ikeyfield2 = 2 
		and fm.qtrrun 
			= (select max(qtrrun) from SHELL_CORP_TEMPDATA_MASTER 
					where datename(year,startdate) = (datename(year,m.startdate)-1) ) )

Временная таблица не подхдит, ибо в ней около 200 000 записей а то и больше.

Что луше сделать, если все отличие одго блок от другого только выборка другого поля как уникального ...

Тоесть задача сводится к тому, что нужно одним запросом(ессно более оптимальным) выбрать 4е поля (каждое содержащее уникальные записи по своему полю из блока
(select distinct fd.third_qtr_current 
		from SHELL_CORP_TEMPDATA_DETAIL as fd, SHELL_CORP_TEMPDATA_MASTER as fm 
		where fm.espkey = fd.parentid 
		and fd.paramname = d.paramname  
		and fm.status='approve' 
		and datename(year,fm.startdate) = (datename(year,m.startdate)-1)  
		and fd.ikeyfield2 = 2 
		and fm.qtrrun 
			= (select max(qtrrun) from SHELL_CORP_TEMPDATA_MASTER 
					where datename(year,startdate) = (datename(year,m.startdate)-1) ) )

Заранее благодарен.
5 ноя 09, 20:17    [7888441]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
locky
Member

Откуда: Харьков, Украина
Сообщений: 62034
Ciget,

cross apply?
5 ноя 09, 20:18    [7888447]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Ciget,

а зачем эти повторы? Это совершенно одинаковые (с точностью до символа) запросы?
И что это за хреновина, убивающая надежду на индекс:
datename(year,fm.startdate) = (datename(year,m.startdate)-1)
??
Зачем там DISTINCT вместо TOP 1 и подзапрос, вычисляющий максимум?

В общем, посмотрите в сторону derived table.
Кстати, а версия сервера какая?
5 ноя 09, 20:30    [7888466]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
Ciget
Member

Откуда:
Сообщений: 134
iap
Ciget,

а зачем эти повторы? Это совершенно одинаковые (с точностью до символа) запросы?
И что это за хреновина, убивающая надежду на индекс:
datename(year,fm.startdate) = (datename(year,m.startdate)-1)
??
Зачем там DISTINCT вместо TOP 1 и подзапрос, вычисляющий максимум?

В общем, посмотрите в сторону derived table.
Кстати, а версия сервера какая?


Вы не внимательны, отличие есть - первое поле по которому и отсуществляеться дистинкт - distinct fd.first_qtr_current, distinct fd.second_qtr_current и так далее .
5 ноя 09, 21:22    [7888565]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Ciget,

так какая же, всё-таки, версия сервера?
Трудный вопрос, да?
5 ноя 09, 21:47    [7888618]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
Ciget
Member

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

MS SQL 2005 (9.00.4053.00)

Вот не пойму в CROSS APPLY как запихнуть уникальность по разным полям ?
6 ноя 09, 13:36    [7891602]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Ciget
iap,

MS SQL 2005 (9.00.4053.00)

Вот не пойму в CROSS APPLY как запихнуть уникальность по разным полям ?
Вам же нужна не уникальность, а просто одна запись (TOP(1)) с датой,
равной максимальной дате за весь предыдущий год (кстати, не ошибка ли это?).
А в этой единственной записи будут и first_qtr_current, и second_qtr_current, и third_qtr_current.
Только вот понадобится не CROSS APPLY, а OUTER APPLY, поскольку записи с такой абсолютно
максимальной датой для указанных Вами ограничений может и не найтись.
Вместо конструкции datename(year,m.startdate) лучше конечно же YEAR(m.startdate)
6 ноя 09, 14:17    [7892014]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
Glory
Member

Откуда:
Сообщений: 104760
Мне кажется, что это скорее PIVOT по кварталам. Который можно и через CASE сделать. За один "проход" таблицы
6 ноя 09, 14:19    [7892039]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
Ciget
Member

Откуда:
Сообщений: 134
Вот что еще волнует будет ли эта конструкция существовать ?
select 
TOP (select count(*) from SHELL_CORP_TEMPDATA_DETAIL)
first_qtr_prev,
(select top(1) mr.first_qtr_current from mr) as first_qtr_prev

from SHELL_CORP_TEMPDATA_DETAIL as d, SHELL_CORP_TEMPDATA_MASTER as m 

cross apply (
select fd.first_qtr_current first_qtr_current from SHELL_CORP_TEMPDATA_DETAIL as fd, SHELL_CORP_TEMPDATA_MASTER as fm 
		where fm.espkey = fd.parentid 
		and fd.paramname = d.paramname
		and datename(year,fm.startdate) = (datename(year,m.startdate)-1)  
		and fm.status='approve' 
		and fd.ikeyfield2 = 2 
		and fm.qtrrun =(select max(qtrrun) from SHELL_CORP_TEMPDATA_MASTER 
					where datename(year,startdate) = (datename(year,m.startdate)-1))) as mr
where m.espkey = d.parentid 
order by d.fieldorder ASC

и почему пишет Msg 4104, Level 16, State 1, Line 1
The multi-part identifier "d.paramname" could not be bound.
Msg 208, Level 16, State 1, Line 1
Invalid object name 'mr'.

в кросс аплай можно же использовать значение внешних по отношению к нему таблиц...
6 ноя 09, 14:22    [7892068]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
Ciget
Member

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

не пойму причем тут максимальная запись ??? стоит же четко - дисктинст - выбираються все уникальные значения колонки ...
6 ноя 09, 14:24    [7892095]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
Ciget
Member

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

Мне кажется, что это скорее PIVOT по кварталам. Который можно и через CASE сделать. За один "проход" таблицы
Можно и его ... но есть одна проблема как и в предыдущем варианте ... ребят - уникальность в каждом квартале поля по которой и будет осуществляться выборка. Если не оно, задача была бы пустяковой.

как сделать возможной выборку уникальных значений разных полей при одной выборке, ну или с минимальными затратами (наиболее оптимальный вариант)?
6 ноя 09, 14:31    [7892185]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Ciget,

если на то пошло, исходный запрос должен обломиться,
если любой из кореллированных подзапросов вернёт 2 различных записи (или больше).
Так что непонятно, при чём тут уникальность. И какая связь между уникальностью и DISTINCTом
6 ноя 09, 14:36    [7892224]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
Glory
Member

Откуда:
Сообщений: 104760
Ciget


как сделать возможной выборку уникальных значений разных полей при одной выборке, ну или с минимальными затратами (наиболее оптимальный вариант)?

Нужно прочитать Рекомендации по оформлению сообщений и задать вопрос на языке понятном большинству. Чтобы неи нужно было угадывать что и из чего должно получится
6 ноя 09, 14:37    [7892229]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
Ciget
Member

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

Так погоди, мож я что-то путаю, но именно distinct обеспечивает выборку уникальных значений поля.

и стартовый запрос работает на ура.
6 ноя 09, 14:38    [7892240]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
Glory
Member

Откуда:
Сообщений: 104760
Ciget
iap,

Так погоди, мож я что-то путаю, но именно distinct обеспечивает выборку уникальных значений поля.

и стартовый запрос работает на ура.

Но distinct не гарантирует возврат запросом строго одной записи.
И если стартовый запрос работает, то лично меня это наталкивает на мысль, что в таблицах уже уникальные данные.

Сообщение было отредактировано: 6 ноя 09, 14:42
6 ноя 09, 14:39    [7892252]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Ciget
iap,

Так погоди, мож я что-то путаю, но именно distinct обеспечивает выборку уникальных значений поля.

и стартовый запрос работает на ура.
Не "уникальных", а "различных". Можно посмотреть в словарь.
6 ноя 09, 14:39    [7892255]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
Ciget
Member

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

Ок
Есть селект который выбирает значение для каждой строки вот он
select distinct fd.first_qtr_current 
		from SHELL_CORP_TEMPDATA_DETAIL as fd, SHELL_CORP_TEMPDATA_MASTER as fm 
		where fm.espkey = fd.parentid 
		and fd.paramname = d.paramname  
		and fm.status='approve' 
		and datename(year,fm.startdate) = (datename(year,m.startdate)-1)  
		and fd.ikeyfield2 = 2 
		and fm.qtrrun 
			= (select max(qtrrun) from SHELL_CORP_TEMPDATA_MASTER 
					where datename(year,startdate) = (datename(year,m.startdate)-1) ) ) as first_qtr_prev

Точно таких блоков - 4 (для каждого квартала). Однако отличиие каждой из них только в выборе уникальных записей конкретного поля. В первом случае - первое поле, во втором выбираються уникальные значения второго поля ... и т.д.

Каким образом сделать наиоптимальнейшую выборку (желательно одним запросом) для получения значения для всех кварталов
6 ноя 09, 14:41    [7892279]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
iap
Ciget
iap,

Так погоди, мож я что-то путаю, но именно distinct обеспечивает выборку уникальных значений поля.

и стартовый запрос работает на ура.
Не "уникальных", а "различных". Можно посмотреть в словарь.
Например, при максимальной startdate может быть 3 first_qtr_current=10 и 5 first_qtr_current=99.
DISTINCT приведёт к тому, что будут две записи (а не одна!) - одна с first_qtr_current=10 и ещё одна с first_qtr_current=99
6 ноя 09, 14:43    [7892311]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
Ciget
Member

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

ок, различных, это не столь важно .. вот вопрос в то что если предикаты одинаковые для всех выборок, отличаются только различностью по разным колонкам...

как бы сделать так, что бы выбрать наиоптимальнейшим вариантом все различные значения для всех кварталов ..
6 ноя 09, 14:49    [7892373]     Ответить | Цитировать Сообщить модератору
 Re: Убрать дублицирующуюся выборку  [new]
Glory
Member

Откуда:
Сообщений: 104760
Ciget
Glory,

Ок
Есть селект который выбирает значение для каждой строки вот он

Поймите. Неинтересно по тексту "неправильного" запроса угадывать решаемую задачу. Дайте входные и выходные данные, а не "навязывайте" свое решение задачи
6 ноя 09, 14:55    [7892439]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить