Yii2属性由虚拟属性+属性,Union Sql到Yii2 AR组成

时间:2017-02-16 11:19:12

标签: php mysql yii2

第一篇文章,但我已经在这里待了几个月,从未注册过(直到今天)。谢谢你的帮助。

问题:

我有两张桌子: T1 & T2

T1是设备表,T2是设备文件表。每个设备的文档都很少,日期为 data_plan 。当在T2中data_plan只是日期时,在T1中data_plan(虚拟属性)由NOW()+ co_zostalo 的间隔计算。 data_plan 作为天数的间隔只有在 T1 co_data = 1 时才能获得。
来自T2的 data_plan 必须是最早的日期。

获得价值我没有任何问题: T1模型中的

public function getNextActionDate() {
    $actModel = new Dzialania();
    $data = new \DateTime();
    if ($this->co_data == 1 && $this->co_zostalo != NULL){
        $data->add(new \DateInterval('P'.$this->co_zostalo.'D'));
        return $data->format('Y-m-d');
    } else if ($this->co_data == 0){ //modul czasookresu wylaczony
        $data = $actModel::find()->where(['id_przyrz_d' => $this->id_przyrz, 'wyk' => 'Nie'])->orderBy('data_plan asc')->one();
        return isset($data) ? $data->data_plan : NULL;
    } else return NULL;
}

当然我声明并使用虚拟属性来收集数据:$ nextActionDate

问题正在对数据进行排序和过滤。

排序

首先尝试:

$query = KartaPrzyrzadu::find()->groupBy(['id_przyrz']);
        $query->joinWith('dzialania');


    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]);

    $dataProvider->sort->attributes['nextActionDate'] = [
        // 1st try 'asc' => ['least(dzialania.data_plan, NOW() + interval co_zostalo day)' => SORT_ASC],
        // 1st try 'desc' => ['least(dzialania.data_plan, NOW() + interval co_zostalo day)' => SORT_DESC]
        // 2nd try 'asc' => [new \yii\db\Expression('CASE WHEN karta_przyrzadu.co_data = 0 THEN dzialania.data_plan END ASC, CASE WHEN co_data = 1 THEN NOW() + interval co_zostalo day END ASC')],
        // 2nd try 'desc' => [new \yii\db\Expression('CASE WHEN karta_przyrzadu.co_data = 0 THEN dzialania.data_plan END DESC, CASE WHEN co_data = 1 THEN NOW() + interval co_zostalo day END DESC')],
    ];

Buuut nope,试图找出它为什么不起作用。 当然还有sql代码。

第二次尝试:通过纯sql(尚未在代码中实现它,我现在正在测试sql) - 这几乎是我需要的。

`SELECT id_przyrz ,MIN(data_plan) as data_plan FROM
(
(SELECT `karta_przyrzadu`.`id_przyrz`, NOW() + interval co_zostalo day as `data_plan` FROM `karta_przyrzadu` WHERE NOT (`karta_przyrzadu`.`status`='Wycofany') and co_data = 0)
UNION
(SELECT `dzialania`.`id_przyrz_d` AS `id_przyrz`, `data_plan` FROM `dzialania` where wyk ="Nie" order by data_plan ASC)
) 
`data_kart` group by id_przyrz ORDER BY `data_plan` DESC`

我需要的是(我认为)内部加入T1表的其余部分,但是如何? (我需要网格中的所有数据,而不仅仅是id_przyrz和data_plan)

过滤

if (!is_null($this->nextActionDate) && strpos($this->nextActionDate, ' - ')     !== false ) {
        list($dateRangeStart, $dateRangeEnd) = explode(' - ', $this->nextActionDate);
            $query->andFilterWhere(['between', 'dzialania.data_plan', $dateRangeStart, $dateRangeEnd])
            ->orFilterWhere(['between', 'NOW() + interval co_zostalo day', $dateRangeStart, $dateRangeEnd]);
        }

我认为有足够的数据来理解这个问题。

由于

找到合适的SQL,现在如何用AR做到这一点?所以我可以正确排序......

SELECT * from (
SELECT id_przyrz, MIN(data_plan) as data_plan FROM
    (
        (SELECT `id_przyrz`, NOW() + interval co_zostalo day as `data_plan` FROM `karta_przyrzadu` WHERE NOT (`status`='Wycofany') and co_data = 0)
        UNION
        (SELECT `id_przyrz_d` AS `id_przyrz`, `data_plan` FROM `dzialania` where wyk ="Nie" order by data_plan ASC)
    ) as `table1` group by id_przyrz ORDER BY `data_plan` DESC
) as `full` left join karta_przyrzadu as full_on on full.id_przyrz = full_on.id_przyrz

0 个答案:

没有答案