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

Откуда:
Сообщений: 10
Есть таблица Salary в которой фиксируются изменения з/п такого вида:
Id ManId ChangedDate Month Year Salary
1 2 10.12.2012 5 2012 50000
2 5 10.12.2012 4 2012 50000
6 2 10.12.2012 7 2012 60000
7 5 10.12.2012 6 2012 55000
8 6 10.12.2012 8 2012 67000

Есть таблица WorkCalendar в которой записан весь календарь с кол-вом рабочих часов для каждого месяца и дня:
Year Month Day Date WorkHoursCount
2012 12 0 NULL 167.0
2012 12 1 2012-12-01 0.0
2012 12 2 2012-12-02 0.0
2012 12 3 2012-12-03 8.0
2012 12 4 2012-12-04 8.0

Необходимо составить запрос который бы выводил следующую информацию
ManId Month Year Salary
2 5 2012 50000
2 6 2012 50000
2 7 2012 60000
2 8 2012 60000
2 9 2012 60000
2 10 2012 60000
2 11 2012 60000
2 12 2012 60000
5 4 2012 50000
5 5 2012 50000
5 6 2012 50000
5 7 2012 50000
5 8 2012 55000
5 9 2012 55000
5 10 2012 55000
5 11 2012 55000
5 12 2012 55000
6 8 2012 67000
6 9 2012 67000
6 10 2012 67000
6 11 2012 67000
6 12 2012 67000

Прошу помощи,
Заранее благодарен.
12 дек 12, 10:07    [13616997]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
iap
Member

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

а просто, на русском языке, сформулировать нельзя? Обязательно в виде шарады?
12 дек 12, 10:12    [13617036]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
vadim511
Member

Откуда:
Сообщений: 10
Извините, думал, что так более наглядно будет. Просто по русски.
В таблице Salary хранятся изменения зарплаты, нужно сделать запрос который вытаскивает определенных пользователей за определенный срок со всеми зарплатами в текущих в этом сроке месяцах.
Т.е. если например, Мне необходимо знать за последние полгода работники 2 и 5 какие зарплаты каждый месяц получали.
Так понятней?
12 дек 12, 10:25    [13617133]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47047
Зачем здесь таблица WorkCalendar?
12 дек 12, 10:30    [13617166]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Добрый Э - Эх
Guest
соединение таблиц по <= или => и делов-то...
12 дек 12, 10:30    [13617168]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31780
Добрый Э - Эх
соединение таблиц по <= или => и делов-то...
Я даже соединения не вижу.

Просто запрос к Salary, с фильтром ManId in (2, 5), раз нужно просто получить зарплаты по месяцам по сотрудникам 2 и 5.
12 дек 12, 10:35    [13617195]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47047
alexeyvg
Добрый Э - Эх
соединение таблиц по <= или => и делов-то...
Я даже соединения не вижу.

Просто запрос к Salary, с фильтром ManId in (2, 5), раз нужно просто получить зарплаты по месяцам по сотрудникам 2 и 5.
Наверно имеется в виду, что зарплата нужна за каждый месяц, упомянутый в WorkCalendar, хотя изменение зарплаты не ежемесячное (май и июль для ManId=2).

Кстати говоря, странно, что зарплата не может поменяться в середине месяца
12 дек 12, 10:41    [13617233]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31780
iap
alexeyvg
Я даже соединения не вижу.

Просто запрос к Salary, с фильтром ManId in (2, 5), раз нужно просто получить зарплаты по месяцам по сотрудникам 2 и 5.
Наверно имеется в виду, что зарплата нужна за каждый месяц, упомянутый в WorkCalendar, хотя изменение зарплаты не ежемесячное (май и июль для ManId=2).
А, ну да, написано "изменения зарплаты", это я невнимательно прочитал...
12 дек 12, 10:44    [13617255]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
vadim511
Member

Откуда:
Сообщений: 10
Ну да зарплата нужна ежемесячно, в середине месяца меняться не может. Запрос уже написал сам.
select ManId, wc.[Month], wc.[Year], (Max(s.Salary)/wc.WorkHoursCount) as Salary
from salary s
join workcalendar wc on Convert(date, cast(s.[Year] as varchar) + '-' + cast(s.[Month] as varchar) + '-01')<=Convert(date, cast(wc.[Year] as varchar) + '-' + cast(wc.[Month] as varchar) + '-01')
where  wc.[Date] is Null
Group by s.manid, wc.[month], wc.[Year], wc.WorkHoursCount
Order by s.manid, wc.year,wc.month

если кто-то может сделать изящней, буду благодарен.
P.S. Просто изначально полез не в ту степь пробовал сделать иерархического вида запрос, c With и Union All
12 дек 12, 10:58    [13617371]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
vadim511
Member

Откуда:
Сообщений: 10
Не знаю, что лучше сделать для производительности, как я с Convert To Date или убрать where и сделать distinct?
12 дек 12, 11:00    [13617388]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31780
alexeyvg
iap
пропущено...
Наверно имеется в виду, что зарплата нужна за каждый месяц, упомянутый в WorkCalendar, хотя изменение зарплаты не ежемесячное (май и июль для ManId=2).
А, ну да, написано "изменения зарплаты", это я невнимательно прочитал...
Тогда что то типа того, только нужен ещё список сотрудников:
select	ManId, 
	[Month], 
	[Year], 
	(
		select top 1 s.Salary 
		from Salary s 
		where s.ManId = m.ManId
			and DATEADD(Month, s.[Month], DATEADD(year, s.[Year], 0)) <= c.[Date]
		order by DATEADD(Month, s.[Month], DATEADD(year, s.[Year], 0)) desc
	) as Salary
from Man m	-- это список сотрудников
	join WorkCalendar c
		on c.[Date] between <указываем диапазон дат>
where m.ManId in (2, 5)

Конечно, идея хранить даты в виде двух полей Year и Month - совершенно дурацкая, нужно будет постоянно вычислять дату и отказываться от индексов.
12 дек 12, 11:00    [13617390]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31780
vadim511
если кто-то может сделать изящней, буду благодарен.
Поизящнее - нужно сделать вместо полей Year, Month, Day нормальные даты.
Это кому же в голову пришло такое, наверное, числа тоже хранятся в отдельных полях по битам :-)
12 дек 12, 11:02    [13617401]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
vadim511
Member

Откуда:
Сообщений: 10
alexeyvg
vadim511
если кто-то может сделать изящней, буду благодарен.
Поизящнее - нужно сделать вместо полей Year, Month, Day нормальные даты.
Это кому же в голову пришло такое, наверное, числа тоже хранятся в отдельных полях по битам :-)

Сделать дату не проблема, дата разделена на месяц и год по соображениям Left Join, он к сожалению нормально не работает с полем дата. Хотя прислушаюсь к Вашим словам и добавлю поле в таблицу, будет и то и другое.

Так ответа не было, что лучше дистинкт на много строк или конверт на одну. Если обратите внимание, в таблице рабочий календарь, месячная сумма часов идет без даты.
12 дек 12, 11:14    [13617529]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
vadim511
Member

Откуда:
Сообщений: 10
автор
нужен ещё список сотрудников

Спасибо, но я подумал сделать из запроса вьюху к которой буду обращаться с ограничениями и джойня другие таблицы.
Большое спасибо.
12 дек 12, 11:19    [13617557]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Гость333
Member

Откуда:
Сообщений: 3683
vadim511
дата разделена на месяц и год по соображениям Left Join, он к сожалению нормально не работает с полем дата

Как это? Пример можете привести?
12 дек 12, 11:25    [13617616]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
Гость333
Как это? Пример можете привести?


у них скорее всего читый datetime ,а там время есть еще ,вот оно у них и не джойнится
12 дек 12, 11:29    [13617662]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
vadim511
Member

Откуда:
Сообщений: 10
Гость333
vadim511
дата разделена на месяц и год по соображениям Left Join, он к сожалению нормально не работает с полем дата

Как это? Пример можете привести?

Щас к сожалению не могу, времени нет, но можете поискать на этом же форуме при соединении таблиц left join по полю типа date left join отрабатывает как обыкновенный join для этого и выделены отдельные столбцы для года месяца и дня.
12 дек 12, 11:30    [13617666]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Maxx
Member [скрыт]

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

да выж там небось в where еще и фильтр по етому же полю прицепили ?
12 дек 12, 11:31    [13617671]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
vadim511
Member

Откуда:
Сообщений: 10
автор
у них скорее всего читый datetime

Хотя может Вы и правы, дело давно было, в подробностях не помню.
12 дек 12, 11:31    [13617677]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
vadim511
Member

Откуда:
Сообщений: 10
Maxx
vadim511,

да выж там небось в where еще и фильтр по етому же полю прицепили ?

Не понял вопроса, это к чему?
12 дек 12, 11:33    [13617698]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
vadim511
Maxx
vadim511,

да выж там небось в where еще и фильтр по етому же полю прицепили ?

Не понял вопроса, это к чему?


автор
при соединении таблиц left join по полю типа date left join отрабатывает как обыкновенный join
12 дек 12, 11:35    [13617712]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
vadim511
Member

Откуда:
Сообщений: 10
Нет, это я проверял, точно помню, а вот замечание насчет datetime может быть вполне обоснованным, база старая, date может еще и не было.
12 дек 12, 11:40    [13617748]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
Гость333
Member

Откуда:
Сообщений: 3683
vadim511
при соединении таблиц left join по полю типа date left join отрабатывает как обыкновенный join


SELECT t1.Id1, t1.Dat1, t2.String
FROM (  SELECT 1 AS Id1, GETDATE() AS Dat1
        UNION ALL
        SELECT 2, GETDATE() + 1
     ) t1
     LEFT OUTER JOIN
     (  SELECT GETDATE() AS Dat2, 'Строка 1' AS String
     ) t2 ON t2.Dat2 = t1.Dat1;


Id1         Dat1                    String
----------- ----------------------- --------
1 2012-12-12 12:05:06.657 Строка 1
2 2012-12-13 12:05:06.657 NULL

Запрос вернул 2 строки, как и полагается добропорядочному left join. А у вас что же, одна строка выдаётся?
12 дек 12, 12:07    [13617988]     Ответить | Цитировать Сообщить модератору
 Re: Помогите составить запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31780
vadim511
Гость333
Как это? Пример можете привести?

Щас к сожалению не могу, времени нет, но можете поискать на этом же форуме при соединении таблиц left join по полю типа date left join отрабатывает как обыкновенный join для этого и выделены отдельные столбцы для года месяца и дня.
:-)

Не бывает такого, это вы что то напутали.
12 дек 12, 12:56    [13618417]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить