@@ -17,8 +17,10 @@ public function __construct($database, $tableName, $resultClassName = NULL, $ali
17
17
$ this ->tableName = $ tableName ;
18
18
$ this ->resultClassName = $ resultClassName ;
19
19
$ this ->alias = $ alias ;
20
- $ this ->projections = array ();
20
+ $ this ->columns = array ();
21
21
$ this ->subqueries = array ();
22
+ $ this ->groupBy = array ();
23
+ $ this ->having = array ();
22
24
$ this ->criterions = array ();
23
25
$ this ->orders = array ();
24
26
$ this ->firstResult = -1 ;
@@ -30,8 +32,10 @@ public function __construct($database, $tableName, $resultClassName = NULL, $ali
30
32
*/
31
33
public function clone () {
32
34
$ rc = new QueryImpl ($ this ->database , $ this ->tableName , $ this ->resultClassName , $ this ->alias );
33
- $ rc ->projections = $ this ->projections ;
35
+ $ rc ->columns = $ this ->columns ;
34
36
$ rc ->subqueries = $ this ->subqueries ;
37
+ $ rc ->groupBy = $ this ->groupBy ;
38
+ $ rc ->having = $ this ->having ;
35
39
$ rc ->criterions = $ this ->criterions ;
36
40
$ rc ->orders = $ this ->orders ;
37
41
$ rc ->firstResult = -1 ;
@@ -70,29 +74,48 @@ public function addOrder(Order ...$orders) {
70
74
* Attention! This class removes any result class name from the query. Use #setResultClass() after calling.
71
75
* @deprecated Use #setColumns() instead
72
76
*/
73
- public function setProjection (Expression ...$ components ) {
74
- return call_user_func_array (array ($ this , 'setColumns ' ), $ components );
77
+ public function setProjection (Expression ...$ expressions ) {
78
+ return call_user_func_array (array ($ this , 'setColumns ' ), $ expressions );
75
79
}
76
80
77
81
/**
78
82
* Set select columns for the query.
79
83
* Attention! This class removes any result class name from the query. Use #setResultClass() after calling.
80
84
*/
81
- public function setColumns (Expression ...$ components ) {
82
- $ this ->projections = array ();
83
- return call_user_func_array (array ($ this , 'addColumns ' ), $ components );
85
+ public function setColumns (Expression ...$ expressions ) {
86
+ $ this ->columns = array ();
87
+ return call_user_func_array (array ($ this , 'addColumns ' ), $ expressions );
84
88
}
85
89
86
90
/**
87
91
* Add select columns for the query.
88
92
*/
89
- public function addColumns (Expression ...$ components ) {
90
- foreach ($ components AS $ c ) {
91
- if ($ c != NULL ) $ this ->projections [] = $ c ;
93
+ public function addColumns (Expression ...$ expressions ) {
94
+ foreach ($ expressions AS $ c ) {
95
+ if ($ c != NULL ) $ this ->columns [] = $ c ;
92
96
}
93
97
return $ this ;
94
98
}
95
99
100
+ /**
101
+ * Add group by columns for the query.
102
+ */
103
+ public function addGroupBy (Expression ...$ expressions ) {
104
+ foreach ($ expressions AS $ c ) {
105
+ if ($ c != NULL ) $ this ->groupBy [] = $ c ;
106
+ }
107
+ return $ this ;
108
+ }
109
+
110
+ /**
111
+ * Add a restriction to constrain the group by result.
112
+ * @return Query - this query for method chaining.
113
+ */
114
+ public function addHaving (Criterion ...$ criterions ) {
115
+ foreach ($ criterions AS $ criterion ) $ this ->having [] = $ criterion ;
116
+ return $ this ;
117
+ }
118
+
96
119
/**
97
120
* Set the index of the first result to be retrieved.
98
121
* @return Query - this query for method chaining.
@@ -215,7 +238,7 @@ public function delete($throwException = FALSE) {
215
238
}
216
239
217
240
public function getSelectSql () {
218
- // SELECT projections
241
+ // SELECT columns
219
242
$ rc = 'SELECT ' .$ this ->getSelectClause ();
220
243
221
244
// FROM table
@@ -227,10 +250,16 @@ public function getSelectSql() {
227
250
$ rc .= ' ' .trim ($ join );
228
251
}
229
252
230
- // GROUP BY projection not implemented yet
253
+ // GROUP BY
231
254
$ group = $ this ->getGroupByClause ();
232
255
if ($ group != NULL ) {
233
- $ rc .= ' ' .$ group ;
256
+ $ rc .= ' GROUP BY ' .$ group ;
257
+
258
+ // HAVING
259
+ $ having = $ this ->getHavingClause ();
260
+ if ($ having != NULL ) {
261
+ $ rc .= ' HAVING ' .$ having ;
262
+ }
234
263
}
235
264
236
265
// WHERE clauses
@@ -298,9 +327,9 @@ public function toSqlString() {
298
327
299
328
public function getSelectClause () {
300
329
$ rc = '' ;
301
- if (($ this ->projections != NULL ) && (count ($ this ->projections ) > 0 )) {
330
+ if (($ this ->columns != NULL ) && (count ($ this ->columns ) > 0 )) {
302
331
$ sql = array ();
303
- foreach ($ this ->projections AS $ p ) {
332
+ foreach ($ this ->columns AS $ p ) {
304
333
$ sql [] = $ p ->toSqlString ($ this , $ this );
305
334
}
306
335
$ rc .= implode (', ' , $ sql );
@@ -330,7 +359,27 @@ public function getJoinClause() {
330
359
}
331
360
332
361
public function getGroupByClause () {
333
- return NULL ;
362
+ $ rc = NULL ;
363
+ if (($ this ->groupBy != NULL ) && (count ($ this ->groupBy ) > 0 )) {
364
+ $ sql = array ();
365
+ foreach ($ this ->groupBy AS $ p ) {
366
+ $ sql [] = $ p ->toSqlString ($ this , $ this );
367
+ }
368
+ $ rc = implode (', ' , $ sql );
369
+ }
370
+ return $ rc ;
371
+ }
372
+
373
+ public function getHavingClause () {
374
+ $ rc = NULL ;
375
+ if (count ($ this ->having ) > 0 ) {
376
+ foreach ($ this ->having AS $ criterion ) {
377
+ if ($ rc != NULL ) $ rc .= ' AND ' ;
378
+ else $ rc = '' ;
379
+ $ rc .= '( ' .$ criterion ->toSqlString ($ this , $ this ).') ' ;
380
+ }
381
+ }
382
+ return $ rc ;
334
383
}
335
384
336
385
public function getWhereClause () {
0 commit comments