1

を使用して非常に複雑なクエリを実行しCSqlDataProvider、ページネーションを機能させようとしていますが、totalItemCount間違ったカウントが返されます。アイテムをカウントするためだけに2番目のSQLを作成しようとしましたが、それは本当に難しいです。誰か助けてもらえますか?

CSqlDataProviderドキュメント:http ://www.yiiframework.com/doc/api/1.1/CSqlDataProvider

コントローラーコード:

    $dayofweek = date('w');     

    $sql = "( SELECT `profile`.`id` as profile_id, `profile`.`name` as profile_name, `events_reminder`.`id`,
                CASE WHEN weekday >= $dayofweek
                    THEN 
                        DATE_FORMAT( CONCAT( DATE_ADD(CURDATE(), INTERVAL weekday - $dayofweek DAY), ' ', event_time ), '%d/%m/%Y %H:%i')
                    ELSE
                        DATE_FORMAT( CONCAT( DATE_ADD(CURDATE(), INTERVAL 7 - $dayofweek + weekday DAY), ' ', event_time ), '%d/%m/%Y %H:%i')
                    END as revent_datetime,
                CASE WHEN weekday >= $dayofweek
                    THEN 
                        DATE_FORMAT( CONCAT( DATE_ADD(CURDATE(), INTERVAL weekday - $dayofweek DAY), ' ', list_time ), '%d/%m/%Y %H:%i')
                    ELSE
                        DATE_FORMAT( CONCAT( DATE_ADD(CURDATE(), INTERVAL 7 - $dayofweek + weekday DAY), ' ', list_time ), '%d/%m/%Y %H:%i')
                    END as rlist_datetime
                FROM events_reminder
                LEFT OUTER JOIN `profiles` `profile` ON (`events_reminder`.`profile_id`=`profile`.`id`)
                HAVING revent_datetime NOT IN (SELECT DATE_FORMAT(event_datetime, '%d/%m/%Y %H:%i') FROM events WHERE `events`.`profile_id`=`events_reminder`.`profile_id`) )
            UNION ALL
            ( SELECT `profile`.`id` as profile_id, `profile`.`name` as profile_name, `events_reminder`.`id`,
                CASE WHEN weekday >= $dayofweek
                    THEN 
                        DATE_FORMAT( CONCAT( DATE_ADD(CURDATE(), INTERVAL weekday - $dayofweek + 7 DAY), ' ', event_time ), '%d/%m/%Y %H:%i')
                    ELSE
                        DATE_FORMAT( CONCAT( DATE_ADD(CURDATE(), INTERVAL 7 - $dayofweek + weekday + 7 DAY), ' ', event_time ), '%d/%m/%Y %H:%i')
                    END as revent_datetime,
                CASE WHEN weekday >= $dayofweek
                    THEN 
                        DATE_FORMAT( CONCAT( DATE_ADD(CURDATE(), INTERVAL weekday - $dayofweek + 7 DAY), ' ', list_time ), '%d/%m/%Y %H:%i')
                    ELSE
                        DATE_FORMAT( CONCAT( DATE_ADD(CURDATE(), INTERVAL 7 - $dayofweek + weekday + 7 DAY), ' ', list_time ), '%d/%m/%Y %H:%i')
                    END as rlist_datetime
                FROM events_reminder
                LEFT OUTER JOIN `profiles` `profile` ON (`events_reminder`.`profile_id`=`profile`.`id`)
                HAVING revent_datetime NOT IN (SELECT DATE_FORMAT(event_datetime, '%d/%m/%Y %H:%i') FROM events WHERE `events`.`profile_id`=`events_reminder`.`profile_id`) )
                ORDER BY revent_datetime";

    $count=Yii::app()->db->createCommand($sql)->queryScalar();

    $dataProvider=new CSqlDataProvider($sql, array(
        'totalItemCount'=>$count,
    ));

    $this->render('index',array(
        'dataProvider'=>$dataProvider,
    ));
4

1 に答える 1

5

は何ですかqueryScalar

SQL ステートメントを実行し、data の最初の行の最初の列の値を返します。

したがって、取得に使用するには、SQL クエリにcounta を追加する必要がありcount(*)ます。これも、次のようにクエリの先頭に追加します。

SELECT count(*), `profile`.`id` as profile_id, `profile`.`name` ...

アップデート:

使用しUNIONているため、外側を移動する必要があるcount(*)ため、エイリアスも指定します。

SELECT count(*) from (((select ...) UNION ALL (select ...)) as alias)

正確な状況では、次のことができます。

$count_sql='SELECT count(*) from (('. $sql .') as alias)';
$count=Yii::app()->db->createCommand($count_sql)->queryScalar();
于 2013-01-25T02:49:49.787 に答える