Gedeon |
Отправлено: 27.05.2004, 16:16 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Че-то уже второй день туплю
одна таблица
id — PK — int, FIO — VARCHAR
вторая
id — int, FWPKey — FK — int, BeginDate — SMALDATETIME, EndDate — SMALLDATETIME
Таблицы связаны по T1.id=T2.FWPKey по соотношению 1 ко многим, как мне получить результат
Id, сумма всех разниц дат (BeginDate — EndDate) в днях например
|
|
AVC |
Отправлено: 27.05.2004, 17:24 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Что типа этого
Select T1.id, Sum(tmpt.dltd)
From T1,
(Select T2.FWPKey, (T2.EndDate — T2.BeginDate) dltd
From T2
Group By FWPKey
) tmpt
Where T1.id = tmpt.FWPKey |
|
olegenty |
Отправлено: 28.05.2004, 07:09 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
а по-мему так:
CODE |
SELECT DISTINCT
ID, BEGINDATE, ENDDATE, SUM(ENDDATE — BEGINDATE)
FROM
TABLE_2
GROUP BY ID, BEGINDATE, ENDDATE
|
|
|
full_lamer |
Отправлено: 28.05.2004, 07:38 |
|
Машинист паровоза
Группа: Участник
Сообщений: 225
|
А помоему даты вычитать нельзя...
Помоему так:
select sum (cast (tend as int) — cast (beg as int)) from demo
ЗЫ. Обычно от большей отнимают меньшее (end — begin)...
|
|
Nick |
Отправлено: 28.05.2004, 08:16 |
|
Машинист паровоза
Группа: Участник
Сообщений: 247
|
А так разве не получается
select FWPKey, Sum (EndDate — BeginDate ) from T2
group by FWPKey
Если допускается Null в датах тогда сложнее |
|
AVC |
Отправлено: 28.05.2004, 08:23 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Опс! Так работает (если это то, что требовалось)
Select T1.id, T1.fio, tmp.dltd
From
T1
,(Select T2.fwpkey, Sum(T2.enddate — T2.begdate) dltd
From T2 Group by T2.fwpkey
) tmp
Where T1.id *= tmp.id1
есть сомнение куда поставить звездочку в синтаксисе MSSql
Результат — список всех из T1 + сумма разниц дат для кождого, если есть в T2 |
|
olegenty |
Отправлено: 28.05.2004, 08:25 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
если я правильно понял вопрос, то подразумевались не все разницы, а разницы всех пар.
|
|
AVC |
Отправлено: 28.05.2004, 08:30 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE | Если допускается Null в датах тогда сложнее |
Скорее всего не очень
Если операции с пустыми запрещены (неполная информация -> вычитать нельзя) то ставим фильтр Where begdate is not null and enddate is not null
или заменяем пустые даты на даты по умолчанию. Наверное MSSql имеет функцию, подобную IsNull(prm1, prm2...), которая находит первый не null'ов аргумент. |
|
Gedeon |
Отправлено: 28.05.2004, 08:54 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
ISNULL есть функция такая, NULL м.б. для каждого id только 1, его меняю на GETDATE(). Запрос сейчас попробую, но идею кажется понял, спасибо, сейчас испытаю напишу, что получилось, там просто все немного сложнее мне надо кол-во полных лет, месяцев, дней для суммы этих дат, но ту функцию я написал, осталось это.
QUOTE |
если я правильно понял вопрос, то подразумевались не все разницы, а разницы всех пар. |
Да правильно сумма разниц всех пар.
ЗЫ Вычитать из одной даты другую не совсем корректно получается есть такая функция DATEDIFF
Отредактировано Gedeon — 28/05/2004, 10:06
|
|
olegenty |
Отправлено: 28.05.2004, 09:10 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
я ещё не весь набор функций MS SQL знаю
|
|
Gedeon |
Отправлено: 28.05.2004, 09:35 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
QUOTE (olegenty @ 28/05/2004, 10:12) | я ещё не весь набор функций MS SQL знаю |
Я тоже
|
|
AVC |
Отправлено: 28.05.2004, 09:42 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
QUOTE (Gedeon @ 28/05/2004, 08:56) | ЗЫ Вычитать из одной даты другую не совсем корректно |
Где как. Но собрались люди грамотные ? |
|
Gedeon |
Отправлено: 28.05.2004, 09:55 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
QUOTE (AVC @ 28/05/2004, 10:44) | QUOTE (Gedeon @ 28/05/2004, 08:56) | ЗЫ Вычитать из одной даты другую не совсем корректно |
Где как. Но собрались люди грамотные ? |
Простите, не пойму Вашего вопроса, помощь Вы мне большую оказали, спасибо всем, сейчас дооформлю все, приведу, что получилось, просто MSSQL ругается на одна дата- вторая в некоторых случаях, если это часть более сложных выражений, а все функции знать по моему просто не реально их там блин немеряно.
|
|
AVC |
Отправлено: 28.05.2004, 10:01 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Вопрос был риторический, утверждающий что воплотить идею каждый в состоянии.
Отредактировано AVC — 28/05/2004, 10:04 |
|
Gedeon |
Отправлено: 28.05.2004, 10:47 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Вот результирующий запрос
SQL | Select WP.id,
Sum(DATEDIFF(dd,WJ.endWork,WJ.beginWork))
From WorkJobTitles WJ,
WorkPeoples WP
WHERE WJ.WPKey=WP.Id
GROUP BY WP.id |
собственно ничего сложного, просто мне это все еще надо в кучу функций передать, поэтому и руки как-то опускались. Бонусом цепляю запрос, который из таблицы WorkPeoples выбирает id и полное количество лет, месяцев и дней прошедшее с даты expirience в этой таблице до сегодня, может пригодиться кому.
SQL | SELECT Id, 'Лет: ' + CAST(
DATEPART(yyyy,GETDATE())-DATEPART(yyyy,expirience)-
CASE
WHEN (DATEPART(mm,GETDATE())<DATEPART(mm,expirience) or (DATEPART(yyyy,GETDATE())=DATEPART(mm,expirience) and DATEPART(dd,GETDATE())<DATEPART(dd,expirience)))
THEN 1
ELSE 0
END AS VARCHAR(3))
+ ', месяцев: ' + CAST(
DATEDIFF(mm,expirience,GETDATE())-
12*(DATEPART(yyyy,GETDATE())-DATEPART(yyyy,expirience)-
CASE
WHEN (DATEPART(mm,GETDATE())<DATEPART(mm,expirience) or (DATEPART(yyyy,GETDATE())=DATEPART(mm,expirience) and DATEPART(dd,GETDATE())<DATEPART(dd,expirience)))
THEN 1
ELSE 0
END) -
CASE
WHEN DATEPART(dd,GETDATE())<DATEPART(dd,expirience)
THEN 1
ELSE 0
END AS VARCHAR(2))
+ ', дней: ' + CAST(
DATEDIFF(dd,DATEADD(month,(DATEDIFF(mm,expirience,GETDATE())-
12*(DATEPART(yyyy,GETDATE())-DATEPART(yyyy,expirience)-
CASE
WHEN (DATEPART(mm,GETDATE())<DATEPART(mm,expirience) or (DATEPART(yyyy,GETDATE())=DATEPART(mm,expirience) and DATEPART(dd,GETDATE())<DATEPART(dd,expirience)))
THEN 1
ELSE 0
END) -
CASE
WHEN DATEPART(dd,GETDATE())<DATEPART(dd,expirience)
THEN 1
ELSE 0
END), DATEADD(year,(DATEPART(yyyy,GETDATE())-DATEPART(yyyy,expirience)-
CASE
WHEN (DATEPART(mm,GETDATE())<DATEPART(mm,expirience) or (DATEPART(yyyy,GETDATE())=DATEPART(mm,expirience) and DATEPART(dd,GETDATE())<DATEPART(dd,expirience)))
THEN 1
ELSE 0
END),expirience)),GETDATE()) AS NVARCHAR(2)) AS Exp
FROM WorkPeoples |
Длинновасто правда и читать тяжело, но работает, я его в UDF засунул поэтому жизнь упрощает.
|
|
AVC |
Отправлено: 28.05.2004, 12:09 |
|
Ветеран
Группа: Модератор
Сообщений: 1583
|
Не сочтите за умничание — может пригодятся идеи. На Oracle последний запрос выглядит так:
SQL | Select
t1.*
,('Лет ' || Floor(Months_between(sysdate, birthday) / 12) ||
', месяцев ' || Floor(Months_between(sysdate, birthday) - Floor(Months_between(sysdate, birthday) / 12)*12) ||
', дней ' || To_Char
(case when To_Number(To_Char(sysdate,'dd')) >= To_Number(To_Char(birthday,'dd'))
then Floor(To_Date(To_Char(sysdate,'dd.') || To_Char(birthday,'mm.yyyy'), 'dd.mm.yyyy') - birthday)
else Floor(sysdate - Add_Months(birthday, Floor(Months_between(sysdate, birthday))))
end)
) age_info
From Tabel.People t1
Where 1 = 1 and birthday is not Null
|
Отредактировано AVC — 28/05/2004, 14:10 |
|
|