[英]How to make sql query to group and sum results by date?
在yii2應用程序中,我有Payment
模型,字段id
(主鍵), u_id
(整數,表示從User
模型進行此付款的人的ID), sum
(整數)和date
。 例:
+--------------------------------+
| Payment |
+--------------------------------+
| id | u_id | sum | date |
+--------------------------------+
| 1 | 1 | 400 | 2015-11-25 |
| 2 | 1 | 200 | 2015-11-25 |
| 3 | 2 | 500 | 2015-11-25 |
| 4 | 2 | 300 | 2015-11-25 |
| 5 | 1 | 100 | 2015-11-20 |
+--------------------------------+
問:我想按日期對結果進行分組,並為每天的每個u_id
匯總所有行的sum
字段,並顯示total
。 怎么做...? 也許沒有total
排? 在yii2 或干凈的mysql 。 結果示例:
+-------------------------------------+
| Date | User id | Money, $ |
+-------------------------------------+
| 2015-11-25 | | 1400 (total) |
| 2015-11-25 | 1 | 600 |
| 2015-11-25 | 2 | 800 |
| 2015-11-20 | | 100 (total) |
| 2015-11-20 | 1 | 100 |
+-------------------------------------+
Payment
:
public function search($params)
{
$query = Payment::find();
// do we need to group and sum here?
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
return $dataProvider;
}
我想ListView
會比GridView
更容易,因為我們將能夠為每個結果進行一些計算。 視圖:
<table>
<thead>
<tr>
<th>Date</th>
<th>User id</th>
<th>Money, $</th>
</tr>
</thead>
<tbody>
<?= ListView::widget([
'dataProvider' => $dataProvider,
'itemView' => '_item_view',
]) ?>
</tbody>
</table>
_item_view
:
<tr>
<td><?= $model->date ?></td>
<td><?= $model->u_id ?></td>
<td><?= $model->sum ?></td>
</tr>
試試這種方式:
select dt "Date", usr "User Id",
case when usr is null
then concat(money, ' (total)')
else money
end as "Money, $"
from (
select dt, null as usr, sum(vsum) as money
from mytable
group by dt
union
select dt, u_id, sum(vsum) as money
from mytable
group by dt, u_id
) a
order by dt desc, coalesce(usr,0)
請在此處查看: http : //sqlfiddle.com/#!9/48102/6
你可以在普通的MySql中使用分析函數,但由於MySql不支持它,你必須模擬它。
在我的解決方案中,我提出了一個只按日期匯總錢的查詢
select dt, null as usr, sum(vsum) as money
from mytable
group by dt
需要null as usr
列,因此我可以將UNION
運算符與第二部分一起使用。 此查詢將匯總所有日期和金額。
然后是第二部分
select dt, u_id, sum(vsum) as money
from mytable
group by dt, u_id
Wich將通過用戶總結錢來獲取所有日期。
第三部分是使它成為子查詢,所以我可以按日期,用戶訂購它。 請記住,第一部分的用戶是null,所以我這樣做,所以每當null變為0
所以它將首先顯示。
您可以這種方式使用SqlDataProvider
$count = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM payment group by `date`, u_id', )->queryScalar();
$dataProvider = new SqlDataProvider([
'sql' => 'SELECT u_id, sum(`sum`) as `sum` , `date` FROM payment group by `date`, u_id',
'totalCount' => $count,
'sort' => [
'attributes' => [
'u_id',
'sum',
'date',
],
],
'pagination' => [
'pageSize' => 20,
],
]);
return $this->render('index', [
'dataProvider' => $dataProvider,
]);
一個選項是讓mysql使用WITH ROLLUP
計算總數。
select dt, u_id, sum(vsum)
from payment
group by dt, u_id with rollup;
+------------+------+-----------+
| dt | u_id | sum(vsum) |
+------------+------+-----------+
| 2015-11-20 | 1 | 100 |
| 2015-11-20 | NULL | 100 |
| 2015-11-25 | 1 | 600 |
| 2015-11-25 | 2 | 800 |
| 2015-11-25 | NULL | 1400 |
| NULL | NULL | 1500 |
+------------+------+-----------+
如果你不想要整體總數,你也可以消除它。
select * from (
select dt, u_id, sum(vsum)
from payment
group by dt, u_id with rollup
) q where dt is not null;
+------------+------+-----------+
| dt | u_id | sum(vsum) |
+------------+------+-----------+
| 2015-11-20 | 1 | 100 |
| 2015-11-20 | NULL | 100 |
| 2015-11-25 | 1 | 600 |
| 2015-11-25 | 2 | 800 |
| 2015-11-25 | NULL | 1400 |
+------------+------+-----------+
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.