Текущий архив: 2005.07.11;
Скачать: CL | DM;
ВнизПересечение промежутков дат Найти похожие ветки
← →
MakNik (2005-05-27 10:43) [0]есть 2 таблицы, содержащие промежутки дат:
Tab1:
DateBegin | DateEnd | Factor
-------------------------------
01.04.2005 | 30.04.2005 | 1
01.05.2005 | 31.05.2005 | 2
...
Tab2:
DateBegin | DateEnd | PR
-------------------------------
01.04.2005 | 15.04.2005 | 20
16.04.2005 | 15.05.2005 | 25
16.05.2005 | 31.05.2005 | 30
...
Помогите, пожалуйста, написать запрос, чтобы получить следующее пересечение таблиц 1 и 2:
Tab3:
DateBegin | DateEnd | Factor | PR
--------------------------------------
01.04.2005 | 15.04.2005 | 1 | 20
16.04.2005 | 30.04.2005 | 1 | 25
01.05.2005 | 15.05.2005 | 2 | 25
16.05.2005 | 31.05.2005 | 2 | 30
← →
Paul_K © (2005-05-27 10:49) [1]жать F1 читать про конструкцию CASE
← →
Johnmen © (2005-05-27 10:51) [2]Хорошо.
Теперь на пальцах расскажи логику.
← →
MakNik (2005-05-27 10:56) [3]
> Теперь на пальцах расскажи логику.
... в общем нужно получить все возможные пересечения значений из Tab1 с Tab2
← →
Johnmen © (2005-05-27 11:00) [4]Абсолютно непонятно.
Напр. что д.б. в итоге в Factor и PR.
← →
paul_k © (2005-05-27 11:01) [5]
> Johnmen © (27.05.05 10:51) [2]
логику он вроде написал
насколько я вижу там перечечение интервалов
то есть если интервалы пересекаются то берет наиболее позднее начало из наиболее раннее окончание из двух инетрвалов.
← →
sniknik © (2005-05-27 11:03) [6]> Теперь на пальцах расскажи логику.
;о)))
Купил новую мясорубку.
Вчера пробовал.
Наконец-то понял, что означает фраза: "Объясни мне на пальцах, как оно работает".
> ... в общем нужно получить все возможные пересечения значений из Tab1 с Tab2
это не все, все, это будет простой запрос с гетерогенным обьедением (те. без усекающих условий)
типа того
SELECT * FROM Tab1, Tab2
но это будет явно отличатся от Tab3, и очень сильно...
← →
sniknik © (2005-05-27 11:05) [7]paul_k © (27.05.05 11:01) [5]
обьясни ты, если понял. я вот тоже чтото не "врубаюсь". как ни смотрел не понимаю что с чем пересекается. (логика) если дополнительно смотреть на значения Factor и PR.
← →
ANB © (2005-05-27 11:10) [8]CREATE TABLE TBL1
(
D1 DATE,
D2 DATE,
N1 NUMBER
)
CREATE TABLE TBL2
(
D1 DATE,
D2 DATE,
N2 NUMBER
)
select * from tbl1, tbl2
where tbl1.d1 < tbl2.d2 and tbl1.d2 > tbl2.d1
Выбор дат DateBegin и DateEnd сделай через case
← →
paul_k © (2005-05-27 11:10) [9]берем интервал из таблицы 1 и значение фактор
пересекаем со всеми значениями из таблицы 2 пересекающимися с ним
получаем первые две строчки
берем второй интервал из таблицы один и делаем тож самое
задачка то интересная.. надо попробовать порешать
← →
paul_k © (2005-05-27 11:11) [10]
> ANB © (27.05.05 11:10) [8] [Новое
> сообщение][Ответить]
не настолько однозначно...
← →
ANB © (2005-05-27 11:17) [11]Это обычное пересечение интервалов. Если нужно что то другое - нужно подробнее писать ТЗ.
← →
Johnmen © (2005-05-27 11:20) [12]>paul_k © (27.05.05 11:10) [9]
Взяли из 1, пересекли, получили N пересечений с PR = 20 и 30.
Так куда теперь девать 20 и 30 ? Какое из них нам надо ?
ЗЫ Задача о пересечении отрезков решается несложно. Весь вопрос в остальных полях...
← →
MakNik (2005-05-27 11:23) [13]
> paul_k © (27.05.05 11:10) [9]
именно это и нужно реализовать
← →
sniknik © (2005-05-27 11:25) [14]а мне интересно по какой логике берутся поля DateBegin/DateEnd то из первой то из второй таблици.
← →
Danilka © (2005-05-27 11:30) [15]что-то типа:
SELECT
T1.DateBegin, T1.DateEnd, T2.DateBegin, T2.DateEnd,
T1.Factor, T2.PR
FROM Tab1 T1, Tab2 T2
WHERE T1.DateBegin BETWEEN T2.DateBegin AND T2.DateEnd
OR T1.DateEnd BETWEEN T2.DateBegin AND T2.DateEnd
?
правда, кажись, нет в МС-Скуле Ороклового GREATEST и LEAST, чтобы из четырех полей с датами в резулитующем наборе собрать два.
:)
← →
MakNik (2005-05-27 11:32) [16]
> Johnmen © (27.05.05 11:20) [12]
для каждого промежутка времени нужно получить все возможные варианты значений Factor и PR.
← →
Danilka © (2005-05-27 11:34) [17][16] MakNik (27.05.05 11:32)
См [15], только в рез. DateBegin надо брать максимальное из T1.DateBegin и T2.DateBegin, а DateEnd - наоборот минимальное. Тогда получится один в один с твоим сабжевым примером.
← →
sniknik © (2005-05-27 11:36) [18]ну не, так не интересно.
что
ANB © (27.05.05 11:10) [8]
что
Danilka © (27.05.05 11:30) [15]
просто вывели все поля с датами, а в выборе нужных как раз весь "цынус" ;о))
> правда, кажись, нет в МС-Скуле Ороклового GREATEST и LEAST, чтобы из четырех полей с датами в резулитующем наборе собрать два.
вместо них есть CASE, приводи как можеш на оракле, я переведу. (если получится ;)
← →
Danilka © (2005-05-27 11:40) [19][18] sniknik © (27.05.05 11:36)
дык, я потом написал - как надо: DateBegin надо брать максимальное из T1.DateBegin и T2.DateBegin, а DateEnd - наоборот минимальное из T1.DateEnd и T2.DateEnd
:)
← →
paul_k © (2005-05-27 11:43) [20]чет я не понимаю
> Danilka © (27.05.05 11:30) [15][Ответить]
select convert(varchar,T1.d1,4) t1d1,
convert(varchar,T1.d2,4) t1d2,
convert(varchar,T2.d1,4) t2d1,
convert(varchar,T2.d2,4) t2d2,
n1,
n2
from Table1 t1,Table2 t2
where (t1.d1 between t2.d1 and t2.d2)
or (t1.d2 between t2.d1 and t2.d2)
хронически возвращает 1 запись:)
← →
sniknik © (2005-05-27 11:44) [21]> дык, я потом написал - как надо:
угу, уже видел
итого
SELECT
CASE WHEN T1.DateBegin > T2.DateBegin THEN T1.DateBegin ELSE T2.DateBegin END AS DateBegin,
CASE WHEN T1.DateEnd < T2.DateEnd THEN T1.DateEnd ELSE T2.DateEnd END AS DateBegin,
T1.Factor, T2.PR
FROM Tab1 T1, Tab2 T2
WHERE T1.DateBegin < T2.DateEnd and T1.DateEnd > T2.DateBegin
← →
ANB © (2005-05-27 11:44) [22]
> paul_k © (27.05.05 11:43) [20]
- возми мой запрос. Ему уже 10 лет. И до сих пор работает.
← →
sniknik © (2005-05-27 11:45) [23]поправка. вместо второго AS DateBegin естественно нужно AS DateEnd
← →
ANB © (2005-05-27 11:46) [24]
> sniknik © (27.05.05 11:44) [21]
- не, ну case можно было и вопрошающего написать заставить. Чтобы не расслаблялся.
← →
paul_k © (2005-05-27 11:48) [25]ANB © (27.05.05 11:44) [22]
1 запись
← →
sniknik © (2005-05-27 11:48) [26]только это все одно не логика, а подгонка к результату... ну если пойдет так, ну значит и слава гейтцу билу. ;)
← →
ANB © (2005-05-27 11:49) [27]Данные и запрос в студию.
← →
sniknik © (2005-05-27 11:50) [28]ANB © (27.05.05 11:46) [24]
а он после будет напрягаться, логические ошибки вылавливать развлечение еще то. ;о))
← →
paul_k © (2005-05-27 11:53) [29]сорри 2 записи:)
t1d1 t1d2 n1
------------------------------ ------------------------------ -----------
01.04.05 30.04.05 1
01.05.04 31.05.04 2
(2 row(s) affected)
t2d1 t2d2 n2
------------------------------ ------------------------------ -----------
01.04.05 15.04.05 20
16.04.05 15.05.05 25
16.05.05 31.05.05 30
(3 row(s) affected)
t1d1 t1d2 t2d1 t2d2 n1 n2
------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- -----------
01.04.05 30.04.05 01.04.05 15.04.05 1 20
01.04.05 30.04.05 16.04.05 15.05.05 1 25
← →
paul_k © (2005-05-27 11:53) [30]select convert(varchar,T1.d1,4) t1d1,
convert(varchar,T1.d2,4) t1d2,
T1.n1
from Table1 t1
select convert(varchar,T2.d1,4) t2d1,
convert(varchar,T2.d2,4) t2d2,
T2.n2
from Table2 t2
select convert(varchar,T1.d1,4) t1d1,
convert(varchar,T1.d2,4) t1d2,
convert(varchar,T2.d1,4) t2d1,
convert(varchar,T2.d2,4) t2d2,
n1,
n2
from Table1 t1,Table2 t2
where t1.d1 <= t2.d2 and t1.d2 >= t2.d1
← →
ANB © (2005-05-27 12:02) [31]Сорри, это у меня по планированию запрос был - это вхождение первого во второе.
То есть надо так :
where (t1.d1 <= t2.d2 and t1.d2 >= t2.d1)
or (t2.d1 <= t1.d2 and t2.d2 >= t1.d1)
← →
paul_k © (2005-05-27 12:07) [32]ANB © (27.05.05 12:02) [31]
а на данных "клиента" тестировал?
t1d1 t1d2 t2d1 t2d2 n1 n2
------------------------------ ------------------------------ ------------------------------ ------------------------------ ----------- -----------
01.04.05 30.04.05 01.04.05 15.04.05 1 20
01.04.05 30.04.05 16.04.05 15.05.05 1 25
← →
paul_k © (2005-05-27 12:10) [33]мать перемать.. когда я данные забивать начну правильно..
у меня вторая строка 1-й таблицы из 4-го года...
← →
paul_k © (2005-05-27 12:11) [34]прошу прощения варианта
select convert(varchar,T1.d1,4) t1d1,
convert(varchar,T1.d2,4) t1d2,
convert(varchar,T2.d1,4) t2d1,
convert(varchar,T2.d2,4) t2d2,
n1,
n2
from Table1 t1,Table2 t2
where (t1.d1 <= t2.d2 and t1.d2 >= t2.d1)
вполне достаточно
← →
Danilka © (2005-05-27 13:50) [35][21] sniknik © (27.05.05 11:44)
угу, что-то я case совсем упустил из виду, видимо с голодухи перед обедом. :)
[34] paul_k © (27.05.05 12:11)
не понял, достаточно для чего? в сабже нет никаких варчаров, и количество полей в результирующем наборе данных не 6, а 4. :)
← →
paul_k © (2005-05-27 14:16) [36]Danilka © (27.05.05 13:50) [35]
А CASE уже sniknik написал
← →
ANB © (2005-05-27 14:24) [37]
> paul_k © (27.05.05 14:16) [36]
По моему ты мне и sniknik пиво должен.
Страницы: 1 вся ветка
Текущий архив: 2005.07.11;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.041 c