|
| 1 | +# The SELECT Statement |
| 2 | + |
| 3 | +## FROM Clause |
| 4 | + |
| 5 | +Consider the following SQL statement: |
| 6 | + |
| 7 | +```sql |
| 8 | +SELECT * FROM products p |
| 9 | +``` |
| 10 | + |
| 11 | +The Query Builder is written as follows to generate the displayed SQL exactly as shown: |
| 12 | + |
| 13 | +```php |
| 14 | +$db->select() |
| 15 | + ->field('*') |
| 16 | + ->from('p', 'products'); |
| 17 | +``` |
| 18 | + |
| 19 | +### Using an Alias in the FROM Clause: |
| 20 | + |
| 21 | +There are generally two ways to write this. In the syntax with two parameters, the first parameter is always the alias, and the second parameter is always the table name: |
| 22 | + |
| 23 | +```sql |
| 24 | +/* ... */ FROM products p |
| 25 | +``` |
| 26 | + |
| 27 | +This is equivalent to |
| 28 | + |
| 29 | +```php |
| 30 | +/* ... */ ->from('p', 'products'); |
| 31 | +``` |
| 32 | + |
| 33 | +### Using the FROM Clause Without an Alias: |
| 34 | + |
| 35 | +If only one parameter is used, it will be interpreted as the table name: |
| 36 | + |
| 37 | +```sql |
| 38 | +/* ... */ FROM products |
| 39 | +``` |
| 40 | + |
| 41 | +This is equivalent to |
| 42 | + |
| 43 | +```php |
| 44 | +/* ... */ ->from('products'); |
| 45 | +``` |
| 46 | + |
| 47 | +## Using Table Fields |
| 48 | + |
| 49 | +Translate table fields to match the following pattern: |
| 50 | + |
| 51 | +```sql |
| 52 | +SELECT |
| 53 | + a.id AS 'ID', |
| 54 | + a.ref AS 'Reference', |
| 55 | + b.name AS 'Name', |
| 56 | + a.description AS 'ProductDescription' |
| 57 | +FROM |
| 58 | + products a |
| 59 | +INNER JOIN |
| 60 | + product_desciptions b ON a.id = b.id |
| 61 | +``` |
| 62 | + |
| 63 | +The alias of a field is used as the key in a PHP associative array, and the SQL expression is the value of the array. |
| 64 | + |
| 65 | +```php |
| 66 | +$fields = [ |
| 67 | + 'ID' => 'a.id', |
| 68 | + 'Reference' => 'a.ref', |
| 69 | + 'Name' => 'b.name', |
| 70 | + 'ProductDescription' => 'a.description' |
| 71 | +]; |
| 72 | +``` |
| 73 | + |
| 74 | +The Query Builder is written as follows to generate the displayed SQL exactly as shown: |
| 75 | + |
| 76 | +```php |
| 77 | +$db->select() |
| 78 | + ->fields([ |
| 79 | + 'ID' => 'a.id', |
| 80 | + 'Reference' => 'a.ref', |
| 81 | + 'Name' => 'b.name', |
| 82 | + 'ProductDescription' => 'a.description' |
| 83 | + ]) |
| 84 | + ->from('a', 'products') |
| 85 | + ->innerJoin('b', 'product_descriptions', 'a.id = b.id'); |
| 86 | +``` |
| 87 | + |
| 88 | +Here’s the enhanced document with additional sections explaining the use of LEFT JOIN, RIGHT JOIN, INNER JOIN, WHERE, HAVING, ORDER BY, LIMIT, OFFSET, and subselects in SQL, along with corresponding examples in PHP Query Builder. |
| 89 | + |
| 90 | +## JOIN Clauses |
| 91 | + |
| 92 | +### INNER JOIN |
| 93 | + |
| 94 | +`INNER JOIN` returns rows when there is a match in both tables. Example SQL: |
| 95 | + |
| 96 | +```sql |
| 97 | +/* ... */ INNER JOIN test2 t2 ON t2.test_id = t1.id AND t2.field1 = 123 |
| 98 | +``` |
| 99 | + |
| 100 | +PHP Query Builder equivalent: |
| 101 | + |
| 102 | +```php |
| 103 | +/* ... */ ->joinInner('t2', 'test2', 't2.test_id = t1.id AND t2.field1 = ?', 123) |
| 104 | +``` |
| 105 | + |
| 106 | +### LEFT JOIN |
| 107 | + |
| 108 | +`LEFT JOIN` returns all rows from the left table, and matched rows from the right table. If there is no match, NULL values are returned for columns from the right table. |
| 109 | + |
| 110 | +Example SQL: |
| 111 | + |
| 112 | +```sql |
| 113 | +LEFT JOIN test3 t3 ON t3.test_id = t1.id |
| 114 | +``` |
| 115 | + |
| 116 | +PHP Query Builder equivalent: |
| 117 | + |
| 118 | +```php |
| 119 | +->joinLeft('t3', 'test3', 't3.test_id = t1.id') |
| 120 | +``` |
| 121 | + |
| 122 | +### RIGHT JOIN |
| 123 | + |
| 124 | +`RIGHT JOIN` returns all rows from the right table, and matched rows from the left table. If there is no match, NULL values are returned for columns from the left table. Example SQL: |
| 125 | + |
| 126 | +```sql |
| 127 | +RIGHT JOIN test4 t4 ON t4.test_id = t1.id |
| 128 | +``` |
| 129 | + |
| 130 | +PHP Query Builder equivalent: |
| 131 | + |
| 132 | +```php |
| 133 | +->joinRight('t4', 'test4', 't4.test_id = t1.id') |
| 134 | +``` |
| 135 | + |
| 136 | +### Using Subselects in JOINs |
| 137 | + |
| 138 | +A subselect can be used as a virtual table in joins. Here’s an example with `RIGHT JOIN`: |
| 139 | + |
| 140 | +```sql |
| 141 | +RIGHT JOIN (SELECT t.id FROM table t WHERE (t.foreign_id=10)) t5 ON t5.test_id = t1.id |
| 142 | +``` |
| 143 | + |
| 144 | +PHP Query Builder equivalent: |
| 145 | + |
| 146 | +```php |
| 147 | +$subSelect = function ($id) use ($mysql) { |
| 148 | + return $mysql->select() |
| 149 | + ->field('t.id') |
| 150 | + ->from('t', 'table') |
| 151 | + ->where('t.foreign_id=?', $id); |
| 152 | +}; |
| 153 | + |
| 154 | +$mysql->joinRight('t5', $subSelect(10), 't5.test_id = t1.id'); |
| 155 | +``` |
| 156 | + |
| 157 | +## WHERE Clause |
| 158 | + |
| 159 | +The `WHERE` clause is used to filter records that meet certain conditions. Example SQL: |
| 160 | + |
| 161 | +```sql |
| 162 | +WHERE t1.field = 'value' |
| 163 | +``` |
| 164 | + |
| 165 | +PHP Query Builder equivalent: |
| 166 | + |
| 167 | +```php |
| 168 | +$mysql->where('t1.field = ?', 'value'); |
| 169 | +``` |
| 170 | + |
| 171 | +The value can be a scalar value (including `null`) and can also be an array of values. The Query Builder will automatically translate value-arrays into an according `IN`-Clause. |
| 172 | + |
| 173 | +## HAVING Clause |
| 174 | + |
| 175 | +The `HAVING` clause is used to filter records after aggregation. It typically applies to grouped results. Example SQL: |
| 176 | + |
| 177 | +```sql |
| 178 | +HAVING customer_count > 10 |
| 179 | +``` |
| 180 | + |
| 181 | +PHP Query Builder equivalent: |
| 182 | + |
| 183 | +```php |
| 184 | +->having('customer_count > 10') |
| 185 | +``` |
| 186 | + |
| 187 | +## ORDER BY Clause |
| 188 | + |
| 189 | +The ORDER BY clause is used to sort the result set by one or more columns. Example SQL: |
| 190 | + |
| 191 | +```sql |
| 192 | +ORDER BY t1.field1 ASC, t1.field2 DESC |
| 193 | +``` |
| 194 | + |
| 195 | +PHP Query Builder equivalent: |
| 196 | + |
| 197 | +```php |
| 198 | +->orderBy('t1.field1') |
| 199 | +->orderBy('t1.field2', 'DESC') |
| 200 | +``` |
| 201 | + |
| 202 | +## LIMIT Clause |
| 203 | + |
| 204 | +The LIMIT clause specifies the maximum number of records to return. Example SQL: |
| 205 | + |
| 206 | +```sql |
| 207 | +LIMIT 100 |
| 208 | +``` |
| 209 | + |
| 210 | +PHP Query Builder equivalent: |
| 211 | + |
| 212 | +```php |
| 213 | +->limit(100) |
| 214 | +``` |
| 215 | + |
| 216 | +## OFFSET Clause |
| 217 | + |
| 218 | +The OFFSET clause is used in conjunction with LIMIT to skip a certain number of rows before beginning to return rows. Example SQL: |
| 219 | + |
| 220 | +```sql |
| 221 | +OFFSET 50 |
| 222 | +``` |
| 223 | + |
| 224 | +PHP Query Builder equivalent: |
| 225 | + |
| 226 | +```php |
| 227 | +->offset(50) |
| 228 | +``` |
| 229 | + |
| 230 | +## Using Subselects |
| 231 | + |
| 232 | +Subselects (or subqueries) are queries nested within another query, often used to retrieve data for specific conditions. |
| 233 | + |
| 234 | +Example SQL for a subselect: |
| 235 | + |
| 236 | +```sql |
| 237 | +SELECT COUNT(*) AS customer_count FROM test1 t1 |
| 238 | +RIGHT JOIN (SELECT t.id FROM table t WHERE (t.foreign_id=10)) t5 ON t5.test_id = t1.id |
| 239 | +``` |
| 240 | + |
| 241 | +PHP Query Builder equivalent with a subselect function: |
| 242 | + |
| 243 | +```php |
| 244 | +$subSelect = function ($id) use ($mysql) { |
| 245 | + return $mysql->select() |
| 246 | + ->field('t.id') |
| 247 | + ->from('t', 'table') |
| 248 | + ->where('t.foreign_id=?', $id); |
| 249 | +}; |
| 250 | + |
| 251 | +$select = $mysql->select() |
| 252 | + ->field('COUNT(*)', 'customer_count') |
| 253 | + ->from('t1', 'test1') |
| 254 | + ->joinRight('t5', $subSelect(10), 't5.test_id = t1.id'); |
| 255 | +``` |
| 256 | + |
| 257 | +# The INSERT Statement |
| 258 | + |
| 259 | +## Basic INSERT |
| 260 | + |
| 261 | +Consider the following SQL statement: |
| 262 | + |
| 263 | +```sql |
| 264 | +INSERT INTO table (field1, field2) VALUES ('value1', 123) |
| 265 | +``` |
| 266 | + |
| 267 | +The Query Builder is written as follows to generate the displayed SQL exactly as shown: |
| 268 | + |
| 269 | +```php |
| 270 | +$db->insert() |
| 271 | + ->into('table') |
| 272 | + ->add('field1', 'value1') |
| 273 | + ->add('field2', 123) |
| 274 | + ->run(); |
| 275 | +``` |
| 276 | + |
| 277 | +### Using Expressions in INSERT |
| 278 | + |
| 279 | +To include SQL expressions directly in the INSERT statement, use `addExpr`: |
| 280 | + |
| 281 | +```sql |
| 282 | +INSERT INTO table (created_at) VALUES (NOW()) |
| 283 | +``` |
| 284 | + |
| 285 | +PHP Query Builder equivalent: |
| 286 | + |
| 287 | +```php |
| 288 | +$db->insert() |
| 289 | + ->into('table') |
| 290 | + ->addExpr('created_at = NOW()') |
| 291 | + ->run(); |
| 292 | +``` |
| 293 | + |
| 294 | +## UPSERT (INSERT ON DUPLICATE KEY UPDATE) |
| 295 | + |
| 296 | +For scenarios where you want to insert a new row or update an existing row if a duplicate key is found, use `addOrUpdate` and `addOrUpdateExpr`: |
| 297 | + |
| 298 | +```sql |
| 299 | +INSERT INTO table (field1, field2, updated_at) VALUES ('value1', 'abc', NOW()) |
| 300 | +ON DUPLICATE KEY UPDATE field2 = VALUES(field2), updated_at = NOW() |
| 301 | +``` |
| 302 | + |
| 303 | +PHP Query Builder equivalent: |
| 304 | + |
| 305 | +```php |
| 306 | +$db->insert() |
| 307 | + ->into('table') |
| 308 | + ->add('field1', 'value1') |
| 309 | + ->addOrUpdate('field2', 'abc') |
| 310 | + ->addOrUpdateExpr('updated_at = NOW()') |
| 311 | + ->run(); |
| 312 | +``` |
| 313 | + |
| 314 | +### Using Expressions with Parameters in UPSERT |
| 315 | + |
| 316 | +To use SQL functions with parameters in UPSERT scenarios, use `addOrUpdateExpr` with placeholders: |
| 317 | + |
| 318 | +```sql |
| 319 | +INSERT INTO table (hash_field) VALUES (MD5('some value to be hashed')) |
| 320 | +ON DUPLICATE KEY UPDATE hash_field = MD5('some value to be hashed') |
| 321 | +``` |
| 322 | + |
| 323 | +PHP Query Builder equivalent: |
| 324 | + |
| 325 | +```php |
| 326 | +$db->insert() |
| 327 | + ->into('table') |
| 328 | + ->addOrUpdateExpr('hash_field = MD5(?)', 'some value to be hashed') |
| 329 | + ->run(); |
| 330 | +``` |
| 331 | + |
| 332 | +## UPDATE Part in UPSERT |
| 333 | + |
| 334 | +To specify assignments only in the `UPDATE` part during an UPSERT scenario, use `update` and `updateExpr`: |
| 335 | + |
| 336 | +```sql |
| 337 | +ON DUPLICATE KEY UPDATE updated_by = 2, update_count = update_count + 1 |
| 338 | +``` |
| 339 | + |
| 340 | +PHP Query Builder equivalent: |
| 341 | + |
| 342 | +```php |
| 343 | +$db->insert() |
| 344 | + ->into('table') |
| 345 | + ->update('updated_by', $userId) |
| 346 | + ->updateExpr('update_count = update_count + 1') |
| 347 | + ->run(); |
| 348 | +``` |
| 349 | + |
| 350 | +This guide provides a structured approach to building INSERT and UPSERT SQL statements using a PHP Query Builder, allowing for clean and maintainable code. |
0 commit comments