Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Получение остатков на каждую дату


Страницы:   1 2

xmen ©   (2010-11-24 19:44:00) 

СУБД Oracle, в БД имеется таблица, в которой одно из полей дата и время, второе сумма операции, третье входящий остаток.

Возможно ли одним запросом получить список входящих остатков на начало каждой из дат, т.е. в одном дне несколько записей имеющих разное время, соответственно остаок на начало имеет наименьшее время.

на выходе нужен список из пар: дата и время, входящий остаток.


Кщд   (2010-11-29 08:46:00) [21]

>xmen   (26.11.10 10:22) [11]
>неаккуратно - поясните.
нет псевдонимов у таблиц и полей - это чревато непредсказуемым результатом запроса

по поводу rownum: т.е. Вам всё равно какой из двух остатков с одним и тем же временем брать?)
пора бы задуматься об уникальном идентификаторе записи или - как минимум - сменить тип поля на timestamp

>Дата и время проводки Входящий остаток
>08.05.2010 08:39:16 -842783,49

с такими данными неудобно работать
>было бы отлично, если бы привели пример исходных данных(напр., >Игорь Шевченко ©   (24.11.10 20:36) [2]) и тех, что нужно получить.


Inovet   (2010-11-26 20:41:00) [22]

> [10] Кщд   (26.11.10 08:03)
> [10] Кщд   (26.11.10 08:03)
> тот вариант, что предложили Вы, не просто не вернет нужного
> результата(т.е. это аналог select your_date, rem from tbl:
> )), но даже не будет выполняться не только на Oracle

Да. Вот так должен работать

SELECT t.your_date, t.rem
FROM tbl t JOIN (
SELECT MIN(your_date) as your_date
FROM tbl
GROUP BY TRUNC(your_date)
) tm ON t.your_date = tm.your_date


Судя по данным в
> [11] xmen   (26.11.10 10:22)

условие
> [0] xmen   (24.11.10 19:44)
> соответственно остаок на начало имеет наименьшее время

невыполнимо, нет уникального признака, какая проводка была первой. Где здесь наименьшее время?

> 08.05.2010 08:39:16 -842783,49
> 08.05.2010 08:39:16 -843337,66


Игорь Шевченко   (2010-11-26 14:11:00) [23]

решение из [2] никак ? заменив MIN на MAX
Насколько я вижу, у тебя остаток все время уменьшается в течение одной даты.


xmen   (2010-11-26 10:22:00) [24]


> >xmen   (25.11.10 17:17) [8]1. трижды обращаетесь к одной
> и той же таблице;2. неаккуратно используете псевдонимы;3.
>  лишние преобразования date-char-date - несмотря на то,
> что Вам в этой ветке рассказали о trunc4. с какой целью
> использован rownum?было бы отлично, если бы привели пример
> исходных данных(напр., Игорь Шевченко ©   (24.11.10 20:36)
> [2]) и тех, что нужно получить.


Действительно трижды - так уж получилось :-)
неаккуратно - поясните.
что trunc используют видел, но во-первых я был не в курсе, что она делает, а во вторых написал свой "шедевр" немного раньше чем ответили на форуме.

Исходные данные такие:

Дата и время проводки Входящий остаток
08.05.2010 08:39:16 -842783,49
08.05.2010 08:39:16 -843337,66
08.05.2010 23:59:59 -843483,49
08.05.2010 23:59:59 -878531,31
08.05.2010 23:59:59 -880921,31
08.05.2010 23:59:59 -884204,83
08.05.2010 23:59:59 -885710,53
08.05.2010 23:59:59 -886010,53
08.05.2010 23:59:59 -888010,53
08.05.2010 23:59:59 -889010,53
08.05.2010 23:59:59 -890010,53
08.05.2010 23:59:59 -985010,53
08.05.2010 23:59:59 -1032020,53
08.05.2010 23:59:59 -1041030,53
08.05.2010 23:59:59 -3343644,68
08.05.2010 23:59:59 -3251024,68
08.05.2010 23:59:59 -3231224,68
08.05.2010 23:59:59 -3118431,91
08.05.2010 23:59:59 -3118481,91
08.05.2010 23:59:59 -3118531,91
08.05.2010 23:59:59 -3118536,49
08.05.2010 23:59:59 -3118561,91
08.05.2010 23:59:59 -3118611,91
08.05.2010 23:59:59 -3118677,58
08.05.2010 23:59:59 -3118727,58
08.05.2010 23:59:59 -3118777,58
08.05.2010 23:59:59 -3118927,58
08.05.2010 23:59:59 -3119077,58
08.05.2010 23:59:59 -3119227,58
08.05.2010 23:59:59 -3121227,58
08.05.2010 23:59:59 -3123227,58
08.05.2010 23:59:59 -3121727,58
08.05.2010 23:59:59 -3120227,58
08.05.2010 23:59:59 -3119227,58
08.05.2010 23:59:59 -3116227,58
08.05.2010 23:59:59 -3113227,58
08.05.2010 23:59:59 -3110222,58
08.05.2010 23:59:59 -3107534,58
08.05.2010 23:59:59 -3105534,58
08.05.2010 23:59:59 -3106034,58
08.05.2010 23:59:59 -3105874,58
08.05.2010 23:59:59 -3103874,58
08.05.2010 23:59:59 -3096874,58
08.05.2010 23:59:59 -3293124,58
08.05.2010 23:59:59 -1293124,58

В итоге нужно получить 08.05.2010 -842783,49
Естественно в исходных данных дней гораздо больше.

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


Кщд   (2010-11-26 08:03:00) [25]

>Inovet ©   (25.11.10 16:09) [7]
тот вариант, что предложили Вы, не просто не вернет нужного результата(т.е. это аналог select your_date, rem from tbl:)), но даже не будет выполняться
не только на Oracle


Кщд   (2010-11-26 07:42:00) [26]

>xmen   (25.11.10 17:17) [8]
1. трижды обращаетесь к одной и той же таблице;
2. неаккуратно используете псевдонимы;
3. лишние преобразования date-char-date - несмотря на то, что Вам в этой ветке рассказали о trunc
4. с какой целью использован rownum?

было бы отлично, если бы привели пример исходных данных(напр., Игорь Шевченко ©   (24.11.10 20:36) [2]) и тех, что нужно получить.


xmen   (2010-11-25 17:17:00) [27]

Всем спасибо, попробую предложенные варианты.

После того как запостил вопрос написал свое решение, оно почему-то очень громоздкое:

Select SS.CID, SS.DayList,
(Select Abs(C_4)
From IBS.VW_CRIT_FULL_RECORDS
Where Collection_Id = SS.CID And
C_1 = TO_DATE(SS.MinTime, 'DD/MM/YYYY HH24:MI:SS') And
RowNum <= 1) Ostatok
From
(Select Days.CID, Days.DayList,
(Select To_Char(Min(C_1), 'DD/MM/YYYY HH24:MI:SS')
From IBS.VW_CRIT_FULL_RECORDS
Where (Collection_Id = Days.CID) And
(C_1 >= TO_DATE(Days.DayList || ' 00:00:00', 'DD/MM/YYYY HH24:MI:SS')) And
(C_1 <= TO_DATE(Days.DayList || ' 23:59:59', 'DD/MM/YYYY HH24:MI:SS'))
) MinTime
From
(Select Distinct CID, DL.DayList
From
(Select Collection_Id CID, TO_CHAR(C_1, 'DD/MM/YYYY') DayList
From IBS.VW_CRIT_FULL_RECORDS
Where (Collection_Id = '4290840243') And
(C_1 >= TO_DATE('06/01/2010 00:00:00', 'DD/MM/YYYY HH24:MI:SS')) And
(C_1 <= TO_DATE('24/11/2010 23:59:59', 'DD/MM/YYYY HH24:MI:SS'))
) DL
) Days
) SS


в данной части на клиенте будут подставлены нужные значения
Where (Collection_Id = '4290840243') And
(C_1 >= TO_DATE('06/01/2010 00:00:00', 'DD/MM/YYYY HH24:MI:SS')) And
(C_1 <= TO_DATE('24/11/2010 23:59:59', 'DD/MM/YYYY HH24:MI:SS'))


Inovet   (2010-11-25 16:09:00) [28]

> [6] Кщд   (25.11.10 11:16)
> если нужно на КАЖДУЮ строку, то двойной FTS - самый последний
> вариант и можно делать так, как предлагал Игорь Шевченко
> - через аналитику:

Я особенносте Оракл не знаю, поэтому и написал "как-то так".


Кщд   (2010-11-25 11:16:00) [29]

>Inovet ©   (24.11.10 22:18) [3]
если нужно на КАЖДУЮ строку, то двойной FTS - самый последний вариант и можно делать так, как предлагал Игорь Шевченко - через аналитику:

WITH foo AS (
SELECT TO_DATE('01.01.2000 01:00','dd.mm.yyyy hh24:mi') your_date, 2 rem FROM dual
UNION ALL
SELECT TO_DATE('01.01.2000 02:00','dd.mm.yyyy hh24:mi') your_date, 1 rem FROM dual
UNION ALL
SELECT TO_DATE('02.01.2000 00:30','dd.mm.yyyy hh24:mi') your_date, 4 rem FROM dual
UNION ALL
SELECT TO_DATE('02.01.2000 02:00','dd.mm.yyyy hh24:mi') your_date, 6 rem FROM dual
)
SELECT g.your_date, g.rem,
     first_value(g.rem) over(partition by trunc(g.your_date) order by g.your_date)    
FROM foo g
order by g.your_date


Кщд   (2010-11-25 10:34:00) [30]

>Получение остатков на каждую дату

WITH foo AS (
SELECT TO_DATE('01.01.2000 01:00','dd.mm.yyyy hh24:mi') your_date, 2 rem FROM dual
UNION ALL
SELECT TO_DATE('01.01.2000 02:00','dd.mm.yyyy hh24:mi') your_date, 1 rem FROM dual
UNION ALL
SELECT TO_DATE('02.01.2000 00:30','dd.mm.yyyy hh24:mi') your_date, 4 rem FROM dual
UNION ALL
SELECT TO_DATE('02.01.2000 02:00','dd.mm.yyyy hh24:mi') your_date, 6 rem FROM dual
)
SELECT trunc(g.your_date),
      min(g.rem ) keep (dense_rank first order by g.your_date)
FROM foo g
GROUP BY trunc(g.your_date)


Игорь Шевченко   (2010-11-24 23:47:00) [31]


> потому что MIN(rem) вряд ли правильно


Значит через аналитику.

WITH foo AS (
SELECT TO_DATE('01.01.2000 01:00','dd.mm.yyyy hh24:mi') your_date, 2 rem FROM dual
UNION ALL
SELECT TO_DATE('01.01.2000 02:00','dd.mm.yyyy hh24:mi') your_date, 1 rem FROM dual
UNION ALL
SELECT TO_DATE('02.01.2000 00:30','dd.mm.yyyy hh24:mi') your_date, 4 rem FROM dual
UNION ALL
SELECT TO_DATE('02.01.2000 02:00','dd.mm.yyyy hh24:mi') your_date, 6 rem FROM dual
)
SELECT your_date,rem FROM foo
 WHERE your_date IN (SELECT DISTINCT MIN(your_date) OVER (PARTITION BY TRUNC(your_date)) FROM foo)


Вылезает
01.01.2000 01:00, 2
02.01.2000 00:30, 4


Inovet   (2010-11-24 22:18:00) [32]

> [2] Игорь Шевченко ©   (24.11.10 20:36)
> SELECT TRUNC(your_date), MIN(rem) FROM foo
> GROUP BY TRUNC(your_date);

Наверно как-то так надо, потому что MIN(rem) вряд ли правильно

SELECT your_date, rem
FROM tbl t LEFT JOIN (
 SELECT MIN(your_date)
 FROM tbl
 GROUP BY TRUNC(your_date)
) tm ON t.your_date = tm.your_date
;


Игорь Шевченко   (2010-11-24 20:36:00) [33]

Или я что-то не понял или без аналитики где-то так:

WITH foo AS (
 SELECT TO_DATE('01.01.2000 01:00','dd.mm.yyyy hh24:mi') your_date, 1 rem FROM dual
 UNION ALL
 SELECT TO_DATE('01.01.2000 02:00','dd.mm.yyyy hh24:mi') your_date, 2 rem FROM dual
 UNION ALL
 SELECT TO_DATE('02.01.2000 01:00','dd.mm.yyyy hh24:mi') your_date, 4 rem FROM dual
 UNION ALL
 SELECT TO_DATE('02.01.2000 02:00','dd.mm.yyyy hh24:mi') your_date, 6 rem FROM dual
)
SELECT TRUNC(your_date), MIN(rem) FROM foo
 GROUP BY TRUNC(your_date);


Игорь Шевченко   (2010-11-24 20:25:00) [34]

Возможно, с использованием аналитических функций.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо