Problem count rows that have the same value in a particular column

Hi everyone, I state that I am not an expert. In my case I am interested in solving a problem of counting rows that have the same value. Now I try to explain better:

  • Manage user: yii2-usuario

  • Tables problems

TABLE managepc-------------------
id_managepc int(11) NOT NULL,
surname int(11) DEFAULT NULL COMMENT ‘Surname’, (already works)
name int(11) DEFAULT NULL COMMENT ‘Name’, (already works)
os int(11) DEFAULT NULL COMMENT ‘O.S.’, --> dropdownlist from table ‘sistop.listsistop’ (already works)
created_at timestamp NULL DEFAULT NULL COMMENT ‘Created at’, (already works)
created_by int(11) DEFAULT NULL COMMENT ‘Created by’, (already works)
updated_at timestamp NULL DEFAULT NULL COMMENT ‘Updated at’, (already works)
updated_by int(11) DEFAULT NULL COMMENT ‘Updated by’ (already works)

TABLE sistop-------------------------
id_sistop int(11) NOT NULL,
listsistop varchar(255) DEFAULT NULL COMMENT ‘O.S.’, ----> Various type
licsistop varchar(80) DEFAULT NULL COMMENT ‘Product KEY’,
qdsistop int(5) DEFAULT NULL COMMENT ‘Q.ty disp.’, --> to insert manually
qusistop int(5) DEFAULT NULL COMMENT ‘Q.ty used’, --> (count how many sames ‘os’ used)
created_at timestamp NULL DEFAULT NULL COMMENT ‘Created at’, (already works)
created_by int(11) DEFAULT NULL COMMENT ‘Created by’, (already works)
updated_at timestamp NULL DEFAULT NULL COMMENT ‘Updated at’, (already works)
updated_by int(11) DEFAULT NULL COMMENT ‘Updated by’ (already works)

  • The list of OS insert in column sistop.listsistop are and I think they should be seen as strings :
    1 Windows 7 PRO x86
    2 Windows 7 PRO x64
    3 Windows 7 ULTIMATE x86
    4 Windows 7 ULTIMATE x64
    5 Windows 7 ENTERPRISE x86
    6 Windows 7 ENTERPRISE x64
    7 Windows 8 ENTERPRISE x86
    8 Windows 8 ENTERPRISE x64
    9 Windows 8 PRO x86
    10 Windows 8 PRO x64
    11 Windows 8.1 PRO x86
    12 Windows 8.1 PRO x64
    13 Windows 10 PRO x86
    14 Windows 10 PRO x64
    15 Windows 10 ENTERPRISE x86
    16 Windows 10 ENTERPRISE x64
    17 Windows SERVER 2003 Standard
    18 Windows SERVER 2008 R2 ENTERPRISE
    19 Windows SERVER 2016
    20 Windows SERVER 2016 DATACENTER

The help that I ask you kindly is this: how should I make the number of times that every single operating system is assigned to a user appear? The count must appear on the ‘qusistop’ column. I think of a query count but I don’t know where to place it and how to write it correctly in the framework. It may be a small problem for many of you, but I can’t find a solution. I thank you in advance.

  • PHP 7.4
  • APACHE
  • MYSQL

Hi!
If I understend you correctly, you should do next:

$sistops = Sistop::find()->select([
// other fields from Sistop table
  'count(os) as  qusistop'
])->leftJoin( Managepc::tableName(), ['os' => 'id_sistop'])
->groupBy('id_sistop');
foreach($sistops->each() as $sistop){
    echo $sistop->qusistop;
// or here you can save $sistop->qusistop
}

I hope you already have the models Sistop and Managepc .

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

GridView::widget([
 'dataProvider' => $dataProvider
]);
1 Like

When I selection a O.S. from dropdownlist (source model Sistop), obviously after save and generate new record/row in Managepc, must compare in this case for row Windows 7 PRO x64 in Sistop in qusistop column the number 1 and so on if I use other O.S.

I apologize for my English, now I try thanks to your help. You have been very kind! I’ll update you on developments! Thanks again.

Use Managepc::afterSave to counting qusistop in Sistop table

I tried to add the query but now it returns me (no value) in all the columns. Below is the Sistop model and the index of the view. If I insert on SistopSearch the above query returns me (no value) on all the columns. I do not know what to think.

app\models\Sistop.php
namespace app\models;

use Da\User\Model\User;
use Yii;
use yii\db\Expression;
use yii\behaviors\TimestampBehavior;
use yii\behaviors\BlameableBehavior;

class Sistop extends \yii\db\ActiveRecord
{
    public static function tableName()
    {
        return '{{%sistop}}';
    }

    public function behaviors()
    {
        return [
            [
                'class' => TimestampBehavior::className(),
                'createdAtAttribute' => 'created_at',
                'updatedAtAttribute' => 'updated_at',
                'value' => new Expression('NOW()'),
            ],
            [
                'class' => BlameableBehavior::className(),
                'createdByAttribute' => 'created_by',
                'updatedByAttribute' => 'updated_by',
            ],
        ];
    }

    public function rules()
    {
        return [
            [['qdsistop', 'qusistop'], 'integer'],
            [['elencosistop'], 'string', 'max' => 255],
            [['elencosistop'], 'unique'],
            [['elencosistop'], 'required'],
            [['licsistop'], 'string', 'max' => 80],
        ];
    }

    public function attributeLabels()
    {
        return [
            'id_sistop' => Yii::t('app', 'ID'),
            'elencosistop' => Yii::t('app', 'Sistema Operativo'),
            'licsistop' => Yii::t('app', 'Product Key'),
            'qdsistop' => Yii::t('app', 'Q.tà disp.'),
            'qusistop' => Yii::t('app', 'Q.tà rim.'),
            'created_at' => Yii::t('app', 'Data inserimento'),
            'created_by' => Yii::t('app', 'Inserito da'),
            'updated_at' => Yii::t('app', 'Data modifica'),
            'updated_by' => Yii::t('app', 'Modificato da'),
        ];
    }

    public function getCreatore()
    {
        return $this->hasOne(User::className(), ['id' => 'created_by']);
    }

    public function getModificatore()
    {
        return $this->hasOne(User::className(), ['id' => 'updated_by']);
    }

    public function getManagepcs()
    {
        return $this->hasMany(Managepc::className(), ['elencosistop' => 'elencosistop']);
    }

    public static function find()
    {
        return new SistopQuery(get_called_class());
    }
}
app\models\SistopSearch.php
namespace app\models;

use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Sistop;

class SistopSearch extends Sistop
{
public function rules()
{
    return [
        [['id_sistop', 'qdsistop', 'qusistop'], 'integer'],
        [['elencosistop', 'licsistop'], 'safe'],
    ];
}

public function scenarios()
{
    return Model::scenarios();
}

public function search($params)
{
    $query = Sistop::find();
    // add conditions that should always apply here
    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]);
    $this->load($params);
    if (!$this->validate()) {
        return $dataProvider;
    }
    // grid filtering conditions
    $query->andFilterWhere([
        'id_sistop' => $this->id_sistop,
        'qdsistop' => $this->qdsistop,
        'qusistop' => $this->qusistop,
        'created_at' => $this->created_at,
        'created_by' => $this->created_by,
        'updated_at' => $this->updated_at,
        'updated_by' => $this->updated_by,
    ]);
    $query->andFilterWhere(['like', 'elencosistop', $this->elencosistop])
        ->andFilterWhere(['like', 'licsistop', $this->licsistop]);
    return $dataProvider;
}
}
app\controllers\SistopController.php
namespace app\controllers;

use Yii;
use app\models\Sistop;
use app\models\SistopSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;

class SistopController extends Controller
{
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['POST'],
                ],
            ],
            'access' => [
                'class' => \yii\filters\AccessControl::className(),
                'rules' => [
                    [
                        'allow' => true,
                        'actions' => ['index', 'view'],
                        'roles' => ['view']
                    ],
                    [
                        'allow' => true,
                        'actions' => ['update'],
                        'roles' => ['update']
                    ],
                    [
                        'allow' => true,
                        'actions' => ['create'],
                        'roles' => ['create']
                    ],
                    [
                        'allow' => true,
                        'actions' => ['delete'],
                        'roles' => ['delete']
                    ],

                    [
                        'allow' => false
                    ]
                ]
            ]
        ];
    }

    public function actionIndex()
    {
        $searchModel = new SistopSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }

    public function actionView($id)
    {
        return $this->render('view', [
            'model' => $this->findModel($id),
        ]);
    }


    public function actionCreate()
    {
        $model = new Sistop();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id_sistop]);
        }

        return $this->render('create', [
            'model' => $model,
        ]);
    }


    public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id_sistop]);
        }

        return $this->render('update', [
            'model' => $model,
        ]);
    }


    public function actionDelete($id)
    {
        $this->findModel($id)->delete();

        return $this->redirect(['index']);
    }


    protected function findModel($id)
    {
        if (($model = Sistop::findOne($id)) !== null) {
            return $model;
        }

        throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.'));
    }
}
app\views\sistop\index.php
use yii\helpers\Html;
use yii\grid\GridView;
use yii\widgets\Pjax;

$this->title = Yii::t('app', 'Elenco Sistemi Operativi');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="sistop-index">

    <h1><?= Html::encode($this->title) ?></h1>

    <p>
        <?= Html::a(Yii::t('app', 'Aggiungi nuovo'), ['create'], ['class' => 'btn btn-success']) ?>
    </p>

    <?php Pjax::begin(); ?>
    <?php // echo $this->render('_search', ['model' => $searchModel]); 
    ?>
    <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],

            //'id_sistop',
            'elencosistop',
            'licsistop',
            'qdsistop',
            'qusistop',
            //'created_at:datetime',
            //[
            //    'attribute' => 'created_by',
            //    'value' => 'creatore.username',
            //],
            //'updated_at:datetime',
            // [
            //    'attribute' => 'updated_by',
            //    'value' => 'modificatore.username',
            //],
            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>

    <?php Pjax::end(); ?>

</div>
app\models\Managepc.php
.......
public function getSistop()
    {
        return $this->hasOne(Sistop::className(), ['id_sistop' => 'os']);
    }

    public function getElencosistop()
    {
        return $this->sistop->elencosistop;
    }
app\models\ManagepcSearch.php
.........................................
    public function search($params)
    {
        $query = Managepc::find();
        $query->joinWith(['nome']);
        $query->joinWith(['cognome']);
        $query->joinWith(['sistop']);
        .................
        ................
$dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        $this->load($params);

        if (!$this->validate()) {
            // uncomment the following line if you do not want to return any records when validation fails
            // $query->where('0=1');
            return $dataProvider;
        }

        // grid filtering conditions
        $query->andFilterWhere([
            'id_managepc' => $this->id_managepc,
        ]);

        $query->andFilterWhere(['like', 'cognome.elencocognome', $this->cognomi])
		       ->andFilterWhere(['like', 'nome.elenconome', $this->nomi])
               ->andFilterWhere(['like', 'sistop.elencosistop', $this->os])
            ...........................................................
			............................................................;
        return $dataProvider;
    }
}
app\views\managepc\_form.php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use app\models\Cognome;
use app\models\Nome;
use app\models\Sistop;
use app\models\...........;
use app\models\...........;
use app\models\...........;
use app\models\...........;
use app\models\...........;


<div class="managepc-form">

    <?php $form = ActiveForm::begin(); ?>

    <div class="row">
        <div class="col-lg-2 col-xs-12">
            <?= $form->field($model, 'cognome')->dropDownList(ArrayHelper::map(Cognome::find()->all(), 'id_cognome', 'elencocognomi'), ['prompt'=>'Seleziona...']) ?>
        </div>
        <div class="col-lg-2 col-xs-12">
            <?= $form->field($model, 'nome')->dropDownList(ArrayHelper::map(Nome::find()->all(), 'id_nome', 'elenconomi'), ['prompt'=>'Seleziona...']) ?>
        </div>
        <div class="col-lg-2 col-xs-12">
            <?= $form->field($model, 'sistop')->dropDownList(ArrayHelper::map(Sistop::find()->all(), 'id_sistop', 'elencosistop'), ['prompt'=>'Seleziona...']) ?>
        </div>
        <div class="col-lg-3 col-xs-12">
            ......................................
        </div>
        <div class="col-lg-3 col-xs-12">
            .....................................
        </div>
    </div>
	
	...............
	
	<?php // echo $form->field($model, 'created_at')->textInput() ?>

    <?php // echo $form->field($model, 'created_by')->textInput() ?>

    <?php // echo $form->field($model, 'updated_at')->textInput() ?>

    <?php // echo $form->field($model, 'updated_by')->textInput() ?>

    <div class="form-group">
        <?= Html::submitButton(Yii::t('app', 'Salva'), ['class' => 'btn btn-success']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>

Hi.
Please, show me the controller in which you create Managepc model
It is ManagepcController I guess.

Add to mapp\models\Managepc.php

public function afterSave($insert, $changedAttributes){
  if($insert){
    // here you increment counters of used OS
    $this->sistop->updateCounters(['qusistop' => 1]);
  }
}

In your app\views\sistop\index.php make changes for ‘qusistop’ attribute of GridView in columns section:

'qusistop' => function($sistopModel) {
  return $sistopModel->getManagepc()->count();
}
  • It should help you to counting used OS.
  • Display counted value of used OS.

Comment out the line in GridView of sistop/index.php

The error must desappear.

Error message is

array_merge(): Expected parameter 2 to be an array, object given

Is it correct defining of relation in Sistop model?

elencosistop’ => ‘elencosistop’ ?!?!?!?

I used this function without problem for relation model Sistop with Managepc. I used this for dropdownlist in form Managepc.

When you comment out of ‘qusistop’ => function()…
The error is disappear?

In _form.php (managepc)

        <?= $form->field($model, 'sistop')->dropDownList(ArrayHelper::map(Sistop::find()->all(), 'id_sistop', 'elencosistop'), ['prompt'=>'Seleziona...']) ?>

Yes if I comment, error not appare but not working.

It seems you incorect definig of relation in Sistop.php
it should be:

public function getManagepcs() { return $this->hasMany(Managepc::className(), ['os' => 'id_sistop']); }

Now i modified

And, what is a result?

Same error

PHP Warning – yii\base\ErrorException

array_merge(): Expected parameter 2 to be an array, object given

This is error

yii\base\ErrorException: array_merge(): Expected parameter 2 to be an array, object given in C:\laragon\www\ngsi\vendor\yiisoft\yii2\grid\GridView.php:550
Stack trace:
#0 [internal function]: yii\base\ErrorHandler->handleError(2, 'array_merge(): ...', 'C:\\laragon\\www\\...', 550, Array)
#1 C:\laragon\www\ngsi\vendor\yiisoft\yii2\grid\GridView.php(550): array_merge(Array, Object(Closure))
#2 C:\laragon\www\ngsi\vendor\yiisoft\yii2\grid\GridView.php(288): yii\grid\GridView->initColumns()
#3 C:\laragon\www\ngsi\vendor\yiisoft\yii2\base\BaseObject.php(109): yii\grid\GridView->init()
#4 [internal function]: yii\base\BaseObject->__construct(Array)
#5 C:\laragon\www\ngsi\vendor\yiisoft\yii2\di\Container.php(400): ReflectionClass->newInstanceArgs(Array)
#6 C:\laragon\www\ngsi\vendor\yiisoft\yii2\di\Container.php(159): yii\di\Container->build('yii\\grid\\GridVi...', Array, Array)
#7 C:\laragon\www\ngsi\vendor\yiisoft\yii2\BaseYii.php(365): yii\di\Container->get('yii\\grid\\GridVi...', Array, Array)
#8 C:\laragon\www\ngsi\vendor\yiisoft\yii2\base\Widget.php(137): yii\BaseYii::createObject(Array)
#9 C:\laragon\www\ngsi\views\sistop\index.php(26): yii\base\Widget::widget(Array)
#10 C:\laragon\www\ngsi\vendor\yiisoft\yii2\base\View.php(348): require('C:\\laragon\\www\\...')
#11 C:\laragon\www\ngsi\vendor\yiisoft\yii2\base\View.php(257): yii\base\View->renderPhpFile('C:\\laragon\\www\\...', Array)
#12 C:\laragon\www\ngsi\vendor\yiisoft\yii2\base\View.php(156): yii\base\View->renderFile('C:\\laragon\\www\\...', Array, Object(app\controllers\SistopController))
#13 C:\laragon\www\ngsi\vendor\yiisoft\yii2\base\Controller.php(386): yii\base\View->render('index', Array, Object(app\controllers\SistopController))
#14 C:\laragon\www\ngsi\controllers\SistopController.php(71): yii\base\Controller->render('index', Array)
#15 [internal function]: app\controllers\SistopController->actionIndex()
#16 C:\laragon\www\ngsi\vendor\yiisoft\yii2\base\InlineAction.php(57): call_user_func_array(Array, Array)
#17 C:\laragon\www\ngsi\vendor\yiisoft\yii2\base\Controller.php(157): yii\base\InlineAction->runWithParams(Array)
#18 C:\laragon\www\ngsi\vendor\yiisoft\yii2\base\Module.php(528): yii\base\Controller->runAction('', Array)
#19 C:\laragon\www\ngsi\vendor\yiisoft\yii2\web\Application.php(103): yii\base\Module->runAction('sistop', Array)
#20 C:\laragon\www\ngsi\vendor\yiisoft\yii2\base\Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request))
#21 C:\laragon\www\ngsi\web\index.php(12): yii\base\Application->run()
#22 {main}
GridView::([
  // ....
  'columns' => [
     // ......
    'elencosistop',
    'licsistop',
    'qdsistop',
     [
        'attribute' => 'qusistop',
         'value' => function($sistopModel){
              return $sisstopModel->getManagepcs()->count();
         }
     ]
   ]
])

Is your code looks like above?

1 Like