如何在yii2'中编写子查询?

时间:2017-04-27 22:52:04

标签: php mysql activerecord yii2

我有这个问题:

select * from dias_clases as dc
inner join clases as cl on cl.clase_id = dc.clase
inner join asistencias as asis on asis.dia_clase = dc.dc_id
where( 
clase in(select ce.clase from clases_estudiantes as ce where ce.estudiante = 321)
or dc_id in (select cr.dia_clase from clase_recuperada as cr where cr.estudiante = 321)
)
and fecha < '2017-04-26'
and cl.disciplina = 9
and dc.estado = 1
group by dc.dc_id
order by dc.fecha desc

它在mysql控制台中运行良好。在Yii2中我需要与活动记录相同的查询,我得到了这个:

$dias_clases = DiasClases::find()
                ->innerJoin("clases as cl", "cl.clase_id = clase")
                ->leftJoin("asistencias as asis", "asis.dia_clase = dc_id")
                ->where("
                    clase in(
                        select ce.clase from clases_estudiantes as ce where ce.estudiante = :estudiante
                    )
                    or dc_id in (
                        select cr.dia_clase from clase_recuperada as cr where cr.estudiante = :estudiante
                    )", [":estudiante" => $estudiante->estudiante_id]
                )
                ->andWhere("fecha < :fecha", [":fecha" => $fecha])
                ->andWhere(["cl.disciplina" => $disciplina])
                ->andWhere(["estado" => DiasClases::TERMINADA])
                ->orderBy(["fecha" => SORT_DESC])
                ->all();

但是&#39;其中&#39;工作不正常。我得到的结果是错误的,我认为这是因为这部分:

where( 
    clase in(select ce.clase from clases_estudiantes as ce where ce.estudiante = 321)
    or dc_id in (select cr.dia_clase from clase_recuperada as cr where cr.estudiante = 321)
    )

的执行方式与在控制台中的执行方式相同。需要括号

2 个答案:

答案 0 :(得分:0)

假设您有clases_estudiantes表的ClasesEstudiantes模型,您可以构建子查询,例如:

$subquery1 = ClasesEstudiantes::find()
      ->select('clase')->andWhere([ 'estudiante'>=  $estudiante])

DiasClases::find()
     ->innerJoin("clases as cl", "cl.clase_id = clase")
     ->leftJoin("asistencias as asis", "asis.dia_clase = dc_id")
     ->where('in', 'clase', $subquery1)
     .......

you can do the same for the other subquery  using `orWhere(   )`

答案 1 :(得分:0)

我去了yii2 github项目并直接询问,这是他们给出的答案,它就像一个魅力:

->where(['or', 
        [
            'in',
            'clase', 
            (new Query)
                ->select('ce.clase')
                ->from('clases_estudiantes')
                ->where(['estudiante' => $estudiante->estudiante_id])
        ],
        [
            'in', 
            'dc_id', 
            (new Query)
                ->select('dia_clase')
                ->from('clase_recuperada')
                ->where(['estudiante' => $estudiante->estudiante_id])
        ]

    ])

这是您要检查的网址: Here