Как использовать вычисленное значение в Oracle SQL count - PullRequest
1 голос
/ 01 августа 2020

На мой взгляд, у меня есть столбец под названием BIRTH_DATE. Я хочу рассчитать возраст, используя этот столбец и сегодняшнюю дату, и подсчитать количество сотрудников в возрастной группе. Например: сотрудники от 40 до 49 лет c.

Другие ответы в форме SQL также приветствуются.

Мой код показан ниже:

$count = StaffEmploymentListView::find()
        ->select([
            'COUNT(*) AS TEACHING_COUNT', 
            'BIRTH_DATE' => 'BIRTH_DATE'
        ])
        ->where(['GENDER' => 'MALE', 'JOB_CADRE' => 'ACADEMIC'])
        ->andFilterHaving(['>=', "TRUNC(months_between(sysdate, BIRTH_DATE) / 12)", 40])
        ->andFilterHaving(['<', "TRUNC(months_between(sysdate, BIRTH_DATE) / 12)", 70])
        ->groupBy(['BIRTH_DATE'])
        ->all();

Я рассчитываю возраст, как показано ниже:

TRUNC(months_between(sysdate, BIRTH_DATE) / 12)

После этого, если я попытаюсь получить доступ к переменной TEACHING_COUNT в модели, она будет равна нулю.

Ответы [ 2 ]

0 голосов
/ 01 августа 2020

Вы можете подсчитать количество записей в возрастной группе без необходимости писать какие-либо SQL.

$from = date('Y-m-d', strtotime('-49 years'));
$to = date('Y-m-d', strtotime('-40 years'));
$query = StaffEmploymentListView::find()
        ->where(['>=', 'BIRTH_DATE', $from])
        ->andWhere(['<=', 'BIRTH_DATE', $to]);

// You can get the count
$count = $query->count();

// Or use the query to display the results
echo Html::tag('h1',
    'Found ' . $query->count() . ' clients born between ' .
    Yii::$app->formatter->asDate($from) . ' and ' . 
    Yii::$app->formatter->asDate($to)
);
$dataProvider = new ActiveDataProvider([
    'query' => $query
]);

echo GridView::widget([
        'dataProvider' => $dataProvider,
        'columns' => [
            'name',
            'BIRTH_DATE:date', 
            [
                'attribute' => 'BIRTH_DATE',
                'value' => static function($model) {
                    return floor((time() - strtotime($model->BIRTH_DATE)) / 31556926);
                },
                'label' => 'Age'
            ]
        ]
]);

Поскольку вы уже используете yii , кажется, имеет смысл использовать его методы напрямую. В этом случае метод count () .

0 голосов
/ 01 августа 2020

Я отвечу SQL примерами. Я не знаю, как приведенный выше код работает в PHP, но из-за группы "BIRTH_DATE" вы получите более одной строки на возраст, и это может быть проблемой при возврате.

Если бы я понял, что вам нужно SUM over count (*), но если запрос не используется повторно где-либо и вам не нужно count per Birth_date, вы просто можете удалить группу by из конструкции запроса.

См. ниже,

create table StaffEmployment
  ( name varchar2(100)
  , gender varchar2(10)
  , job_cadre varchar2(50)
  , birth_date date
  );
----------------------------------------------------------------------  
insert all
  into staffemployment(name,gender,job_cadre,birth_date)
  values('A','M','Acdemic',sysdate-(45*365))
  into staffemployment(name,gender,job_cadre,birth_date)
  values('B','M','Acdemic',sysdate-(45*365))
  into staffemployment(name,gender,job_cadre,birth_date)
  values('C','F','Acdemic',sysdate-(70*365))
  into staffemployment(name,gender,job_cadre,birth_date)
  values('D','F','Acdemic',sysdate-(10*365))
SELECT * FROM dual;
----------------------------------------------------------------------  
select t.*,TRUNC(months_between(sysdate, BIRTH_DATE) / 12) age
 from StaffEmployment t;
----------------------------------------------------------------------  
NAME   GENDER     JOB_CADRE  BIRTH_DAT        AGE
----- ----------  ---------- --------- ----------
A      M          Acdemic    13-AUG-75         44
B      M          Acdemic    13-AUG-75         44
C      F          Acdemic    19-AUG-50         69
D      F          Acdemic    04-AUG-10          9
---------------------------------------------------------------------- 
select BIRTH_DATE,count(*)
  from StaffEmployment t
 where TRUNC(months_between(sysdate, BIRTH_DATE) / 12) >= 40 
   and TRUNC(months_between(sysdate, BIRTH_DATE) / 12) < 70
 group by BIRTH_DATE;
----------------------------------------------------------------------  
BIRTH_DAT   COUNT(*)
--------- ----------
13-AUG-75          2
19-AUG-50          1
----------------------------------------------------------------------  
And if we do a sum you get the actual count over all rows
----------------------------------------------------------------------  
select SUM(count(*)) teacing_count
  from StaffEmployment t
 where TRUNC(months_between(sysdate, BIRTH_DATE) / 12) >= 40 
   and TRUNC(months_between(sysdate, BIRTH_DATE) / 12) < 70
 group by BIRTH_DATE;
---------------------------------------------------------------------- 
TEACING_COUNT
-------------
            6
...