К сожалению, во всех предыдущих ответах отсутствуют некоторые детали. Правильное решение немного громоздко, но это единственный способ сделать это правильно.
Вот как вы можете это сделать, точно сохраняя все детали и удобство использования:
A
и B
могут включать Ah и Bh в любом порядке Создайте два файла: A_def.h, B_def.h. Они будут содержать только определения A
и B
:
// A_def.h
#ifndef A_DEF_H
#define A_DEF_H
class B;
class A
{
int _val;
B *_b;
public:
A(int val);
void SetB(B *b);
void Print();
};
#endif
// B_def.h
#ifndef B_DEF_H
#define B_DEF_H
class A;
class B
{
double _val;
A* _a;
public:
B(double val);
void SetA(A *a);
void Print();
};
#endif
И тогда, Ah и Bh будут содержать это:
// A.h
#ifndef A_H
#define A_H
#include "A_def.h"
#include "B_def.h"
inline A::A(int val) :_val(val)
{
}
inline void A::SetB(B *b)
{
_b = b;
_b->Print();
}
inline void A::Print()
{
cout<<"Type:A val="<<_val<<endl;
}
#endif
// B.h
#ifndef B_H
#define B_H
#include "A_def.h"
#include "B_def.h"
inline B::B(double val) :_val(val)
{
}
inline void B::SetA(A *a)
{
_a = a;
_a->Print();
}
inline void B::Print()
{
cout<<"Type:B val="<<_val<<endl;
}
#endif
Обратите внимание, что A_def .h и B_def.h являются «частными» заголовками, пользователи A
и B
не должны их использовать. Общий заголовок - A.h и B.h.
Изменение запроса Бена немного,
select count(distinct switch_id)
from xx_new.xx_cti_call_details@appsread.prd.com
where dealer_name = 'XXXX'
and creation_date between add_months(trunc(sysdate,'mm'),-1) and last_day(add_months(trunc(sysdate,'mm'),-1))
Данные за последний месяц -
select count(distinct switch_id)
from xx_new.xx_cti_call_details@appsread.prd.com
where dealer_name = 'XXXX'
and to_char(CREATION_DATE,'MMYYYY') = to_char(add_months(trunc(sysdate),-1),'MMYYYY');
Функция trunc()
усекает дату до указанного периода времени; поэтому trunc(sysdate,'mm')
вернет начало текущего месяца. Затем вы можете использовать функцию add_months()
, чтобы получить начало предыдущего месяца, примерно так:
select count(distinct switch_id)
from xx_new.xx_cti_call_details@appsread.prd.com
where dealer_name = 'XXXX'
and creation_date >= add_months(trunc(sysdate,'mm'),-1)
and creation_date < trunc(sysdate, 'mm')
Как небольшая сторона, вы не явно преобразование в дату в исходном запросе. Всегда делают это, используя либо литерал date , например. DATE 2012-08-31
или to_date()
, например to_date('2012-08-31','YYYY-MM-DD')
. Если вы этого не сделаете, вы обязательно получите это неправильно в какой-то момент.
Вы не использовали бы sysdate - 15
, поскольку это обеспечило бы дату за 15 дней до текущей даты, которая, похоже, не является что вам нужно. Он также будет включать компонент времени, поскольку вы не используете trunc()
.
Как небольшая демонстрация того, что делает trunc(<date>,'mm')
:
select sysdate
, case when trunc(sysdate,'mm') > to_date('20120901 00:00:00','yyyymmdd hh24:mi:ss')
then 1 end as gt
, case when trunc(sysdate,'mm') < to_date('20120901 00:00:00','yyyymmdd hh24:mi:ss')
then 1 end as lt
, case when trunc(sysdate,'mm') = to_date('20120901 00:00:00','yyyymmdd hh24:mi:ss')
then 1 end as eq
from dual
;
SYSDATE GT LT EQ
----------------- ---------- ---------- ----------
20120911 19:58:51 1
Я полагаю, что это также сработало бы:
select count(distinct switch_id)
from xx_new.xx_cti_call_details@appsread.prd.com
where
dealer_name = 'XXXX'
and (creation_date BETWEEN add_months(trunc(sysdate,'mm'),-1) and trunc(sysdate, 'mm'))
У него есть преимущество в использовании BETWEEN , который использовал OP в качестве критериев выбора даты.
Получение последних данных за девятый месяц
SELECT * FROM TABLE_NAME
WHERE DATE_COLUMN BETWEEN '&STARTDATE' AND '&ENDDATE';