【问题标题】:How to use a calculated value in Oracle SQL count如何在 Oracle SQL 计数中使用计算值
【发布时间】:2020-11-22 02:56:39
【问题描述】:

在我看来,我有一个名为 BIRTH_DATE 的列。我想使用该列和今天的日期计算年龄,并计算年龄范围内的员工人数。例如:40 到 49 之间的员工等。

也欢迎使用普通 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 变量,则它为空。

【问题讨论】:

    标签: php sql oracle activerecord yii2


    【解决方案1】:

    您可以计算一个年龄段之间的记录数,而无需写任何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() 方法。

    【讨论】:

      【解决方案2】:

      我将用 SQL 示例来回答。我不知道上面的代码在 PHP 中是如何工作的,但是由于按“BIRTH_DATE”分组,每个年龄会得到不止一行,并且在返回时可能会出现问题。

      如果我理解您需要的是 SUM over count(*) 但如果查询没有在任何地方重复使用并且您不需要 count perbirth_date 您只需从查询构造中删除 group 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-06
        • 2021-10-13
        • 2022-01-18
        • 1970-01-01
        • 2019-12-08
        • 2022-12-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多