首頁 > php教程 > PHP开发 > 主體

Sequelize中用group by進行分組聚合查詢

高洛峰
發布: 2016-12-28 11:30:46
原創
3112 人瀏覽過

一、SQL與Sequelize中的分組查詢

1.1 SQL中的分組查詢

SQL查詢中,通GROUP BY語名實現分組查詢。 GROUP BY子句要和聚合函數搭配使用才能完成分組查詢,在SELECT查詢的欄位中,如果沒有使用聚合函數就必須出現在ORDER BY子句中。分組查詢後,查詢結果為一個或多個列分組後的結果集。

GROUP BY語法

SELECT 列名, 聚合函数(列名)
FROM 表名
WHERE 列名 operator value
GROUP BY 列名 
[HAVING 条件表达式] [WITH ROLLUP]
登入後複製

在上述語句中:

聚合函數- 分組查詢通常要與聚合函數一起使用,聚合函數包括:

     COUNT()-用於統計記錄條數🎠

     COUNT()-用於統計記錄條數🠎用於計算欄位的值的總和

     AVG()-用於計算欄位的值的平均值

     MAX-用於尋找查詢欄位的最大值

    欄位 MIX-用於尋找查詢欄位的最大值


   GROUP BY子名-用於指定分組的欄位


HAVING子名-用於過濾分組結果,符合條件表達式的結果將會被顯示


WITH ROLLUP子名-用於指定追加一條記錄,用於匯總前面的​​資料

1.2 Sequelize中的分組查詢


使用聚合函數

Sequelize提供了聚合函數,可以直接對模型進行聚合查詢:

aggregate(field, aggregateFunction, [octions的聚合函數進行查詢

sum(field, [options])-求和

count(field, [options])-統計查詢結果數

max(field, [options])-查詢最大值

min (field, [options])-查詢最小值


以上這些聚合函數中,可以透過options.attributes、options.attributes屬性指定分組相關字段,並可以透過​​options.having指定過濾條件,但沒有直接指定WITH ROLLUP子句的參數。

如,使用.sum()查詢訂單數量大於1的使用者訂單金額:

Order.sum('price', {attributes:['name'], group:'name', plain:false, having:['COUNT(?)>?', 'name', 1]}).then(function(result){
 console.log(result);
})
登入後複製

產生的SQL語句如下:

SELECT `name`, sum(`price`) AS `sum` FROM `orders` AS `Orders` GROUP BY name HAVING COUNT('name')>1;
登入後複製
登入後複製

使用聚合參數

除直接使用聚合函數外,也可以在findAll()等方法中,指定聚合查詢相關參數實作聚合查詢。查詢時,同樣可以透過透過options.attributes、options.attributes屬性指定分組相關字段,並可透過options.having指定篩選條件。與直接使用聚合函數查詢不一樣,透過參數建構聚合查詢時,要以陣列或物件形式設定options.attributes參數中的聚合字段,並需要透過sequelize.fn()方法傳入聚合函數。

如,使用.findAll()查詢訂單數量大於1的使用者訂單金額:

Order.findAll({attributes:['name', [sequelize.fn('SUM', sequelize.col('price')), 'sum']], group:'name', having:['COUNT(?)>?', 'name', 1], raw:true}).then(function(result){
 console.log(result);
})
登入後複製

產生的SQL語句如下:

SELECT `name`, sum(`price`) AS `sum` FROM `orders` AS `Orders` GROUP BY name HAVING COUNT('name')>1;
登入後複製
登入後複製

二、使用範例


2.1 簡單使用

使用分組查詢,統計每位客戶的訂單總額。

使用SQL語句,可以像下面這樣查詢:

> select * from orders;
+---------+-------------+--------+-----------+---------------------+
| orderId | orderNumber | price | name  | createdOn   |
+---------+-------------+--------+-----------+---------------------+
|  1 | 00001  | 128.00 | 张小三 | 2016-11-25 10:12:49 |
|  2 | 00002  | 102.00 | 张小三 | 2016-11-25 10:12:49 |
|  4 | 00004  | 99.00 | 王小五 | 2016-11-25 10:12:49 |
|  3 | 00003  | 199.00 | 赵小六 | 2016-11-25 10:12:49 |
+---------+-------------+--------+-----------+---------------------+
登入後複製

   

而在Sequelize中可以像下面這樣實現:

> select name, SUM(price) from orders GROUP BY name;
+-----------+------------+
| name  | SUM(price) |
+-----------+------------+
| 张小三 |  230.00 |
| 王小五 |  99.00 |
| 赵小六 |  199.00 |
+-----------+------------+
登入後複製

   

2.2 使用HAVING子句

統計訂單數量大於1的用戶的訂單總金額。

使用SQL語句,可以像下面這樣實作:

Order.findAll({attributes:['sum', [sequelize.fn('SUM', sequelize.col('name')), 'sum']], group:'name', raw:true}).then(function(result){
 console.log(result);
})
登入後複製

   

而使用Sequelize可以像下面這樣查詢:

> select name, SUM(price) from orders GROUP BY name HAVING count(1)>1;
+-----------+------------+
| name  | SUM(price) |
+-----------+------------+
| 张小三 |  230.00 |
| 赵小六 |  199.00 |
+-----------+------------+
登入後複製
RO LLUP子句是MySQL 5.5+新增的特性,用於總結統計結果。但本文發佈時,Sequelize還不支援該特性。

增加總和統計列:

Order.findAll({attributes:['sum', [sequelize.fn('SUM', sequelize.col('name')), 'sum']], group:'name', having:['COUNT(?)>?', 'name', 1], raw:true}).then(function(result){
 console.log(result);
})
登入後複製

   

2.4 連接查詢與分組

為了管理方便,我們會將不同的資訊保存在不同的資料表中。如,我們會將訂單資訊放在一張表中,而將客戶資訊保存在另一張表中。對於存在關聯關係的兩張表,我們會使用連接查詢來尋找關聯數據,在進行連接查詢時,同樣可以使用聚合函數。

訂單表如下:

> select name, SUM(price) from orders GROUP BY name WITH ROLLUP;
+-----------+------------+
| name  | SUM(price) |
+-----------+------------+
| 张小三 |  230.00 |
| 王小五 |  99.00 |
| 赵小六 |  199.00 |
| NULL  |  528.00 |
+-----------+------------+
登入後複製

   

客戶表結構如下:

> select * from orders;
+---------+-------------+--------+------------+---------------------+
| orderId | orderNumber | price | customerId | createdOn   |
+---------+-------------+--------+------------+---------------------+
|  1 | 00001  | 128.00 |   1 | 2016-11-25 10:12:49 |
|  2 | 00002  | 102.00 |   1 | 2016-11-25 10:12:49 |
|  3 | 00003  | 199.00 |   4 | 2016-11-25 10:12:49 |
|  4 | 00004  | 99.00 |   3 | 2016-11-25 10:12:49 |
+---------+-------------+--------+------------+---------------------+
登入後複製

   


使用每個客戶並分配訂單,使用每個客戶的訂單統計數據。

使用SQL語句查詢如下:

> select * from customers;
+----+-----------+-----+---------------------+---------------------+
| id | name  | sex | birthday   | createdOn   |
+----+-----------+-----+---------------------+---------------------+
| 1 | 张小三 | 1 | 1986-01-22 08:00:00 | 2016-11-25 10:16:35 |
| 2 | 李小四 | 2 | 1987-11-12 08:00:00 | 2016-11-25 10:16:35 |
| 3 | 王小五 | 1 | 1988-03-08 08:00:00 | 2016-11-25 10:16:35 |
| 4 | 赵小六 | 1 | 1989-08-11 08:00:00 | 2016-11-25 10:16:35 |
+----+-----------+-----+---------------------+---------------------+
登入後複製

   

Sequelize中連接查詢時,首先需要建立模型間的關聯關係:

> select c.name, SUM(o.price) AS sum from customers AS c INNER JOIN orders AS o ON o.customerId =c.id GROUP BY c.name;
登入後複製

   

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或工作能帶來一定的幫助,如果有疑問大家可以留言交流。

更多Sequelize中用group by進行分組聚合查詢相關文章請關注PHP中文網!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門推薦
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板