|
| 1 | +# Select |
| 2 | + |
| 3 | +This page covers many concepts on how to retrieve data using the query builder. But there are still a lot of tricks how to use the query builder, which are not documented on this page yet. |
| 4 | + |
| 5 | +Feel free to submit a PR and improve something about this site. |
| 6 | + |
| 7 | +## Fields |
| 8 | + |
| 9 | +```php |
| 10 | +use Kir\MySQL\Builder\Expr\DBOrderSpec;use Kir\MySQL\Databases\MySQL; |
| 11 | + |
| 12 | +$pdo = new PDO(/* ... */); |
| 13 | +$db = new MySQL($pdo); |
| 14 | + |
| 15 | +// One method call for each field specifications |
| 16 | +$rows = $db->select() |
| 17 | +->field('t.field1') |
| 18 | +->field('t.field2', 'alias') |
| 19 | +->from('t', 'some_table') |
| 20 | +->fetchRows(); |
| 21 | + |
| 22 | +// Field specifications in an array notation |
| 23 | +$rows = $db->select() |
| 24 | +->fields([ |
| 25 | + 'alias1' => 't.field1', |
| 26 | + 'alias2' => 't.field2' |
| 27 | +]) |
| 28 | +->from('t', 'some_table') |
| 29 | +->fetchRows(); |
| 30 | +``` |
| 31 | + |
| 32 | +## Receiving data |
| 33 | + |
| 34 | +```php |
| 35 | +use Kir\MySQL\Builder\Expr\DBOrderSpec;use Kir\MySQL\Databases\MySQL; |
| 36 | + |
| 37 | +$db = new MySQL(new PDO(/* ... */)); |
| 38 | + |
| 39 | +$select = $db->select() |
| 40 | +->field('t.field1') |
| 41 | +->field('t.field2') |
| 42 | +->from('t', 'test'); |
| 43 | + |
| 44 | +// Get multiple rows as a Key/Value-Array (like PDO::FETCH_ASSOC) |
| 45 | +// Result is guaranteed to be an array<int, array<string, string>>. |
| 46 | +// Might throw an exception. |
| 47 | +$rows = $select->fetchRows(); |
| 48 | + |
| 49 | +// Get one row as a Key(=Fieldnames)/Value(=Values)-Array (like PDO::FETCH_ASSOC) |
| 50 | +// Result is guaranteed to be an array<string, string> or an empty array. |
| 51 | +// Might throw an exception. |
| 52 | +$row = $select->fetchRow(); |
| 53 | + |
| 54 | +// Get the value of the first column of the result-set. |
| 55 | +// No value means `null`. |
| 56 | +$value = $select->fetchValue(); |
| 57 | +``` |
| 58 | + |
| 59 | +### Keep the original database types |
| 60 | + |
| 61 | +PDO returns all data as `string` or `null`. However, via the meta data of the last query you can read out the types of the last query. With the method `setPreserveTypes()` one can have the types used in the database largely reconstructed on output. This costs a little performance. On modern systems this should not be too noticeable. But in fact only integers and decimal numbers are translated at the moment. Everything else remains `string` or `null`. If a `null` value is returned from the database, then of course this value is kept. |
| 62 | + |
| 63 | +## Optional conditions |
| 64 | + |
| 65 | +Sometimes you want to set conditions based on dynamic data. One example would be a grid-list with dynamic filters for certain columns. Following the example below, you can predefine _optional conditions_ which will execute when the corresponding data in the `$filter`-Array is present. |
| 66 | + |
| 67 | +```PHP |
| 68 | +use Kir\MySQL\Databases\MySQL; |
| 69 | +use Kir\MySQL\Builder\Expr\DBExprFilter; |
| 70 | +use Kir\MySQL\Builder\Value\DBOptionalValue; |
| 71 | + |
| 72 | +$filter = [ |
| 73 | + 'name' => 'Peter', |
| 74 | + 'date' => [ |
| 75 | + 'start' => '2016-05-01', |
| 76 | + 'end' => '2016-05-31', |
| 77 | + ], |
| 78 | +]; |
| 79 | + |
| 80 | +$query = (new MySQL(new PDO(/* ... */))) |
| 81 | +/* ... */ |
| 82 | +->from('t', 'test') |
| 83 | +/* ... */ |
| 84 | +->where(new DBExprFilter('t.name = ?', $filter, 'name')) |
| 85 | +->where(new DBExprFilter('t.date >= ?', $filter, 'date.start')) // Key in dot-notation |
| 86 | +->where(new DBExprFilter('t.date <= ?', $filter, ['date', 'end'])) // Key in array-notation |
| 87 | +->limit(new DBOptionalValue($filter, ['count'])) |
| 88 | +->offset(new DBOptionalValue($filter, ['offset'])) |
| 89 | +->fetchRows(); |
| 90 | +``` |
| 91 | + |
| 92 | +You can also define validation rules to only match certain data in `$filter`. |
| 93 | + |
| 94 | +## Sorting from data |
| 95 | + |
| 96 | +```php |
| 97 | +use Kir\MySQL\Databases\MySQL; |
| 98 | +use Kir\MySQL\Builder\Expr\DBOrderSpec; |
| 99 | + |
| 100 | +$db = new MySQL(new PDO(/* ... */)); |
| 101 | + |
| 102 | +// [alias => dir, alias => dir, ...] |
| 103 | +$_GET = ['field3' => 'ASC', 'field1' => 'ASC', 'field2' => 'ASC', 'field4' => 'ASC']; |
| 104 | + |
| 105 | +$rows = $db->select() |
| 106 | +->field('t.field1') |
| 107 | +->field('t.field2') |
| 108 | +->from('t', 'test') |
| 109 | +->orderBy(new DBOrderSpec([ |
| 110 | + 'field1' => 't.field1', // alias => db-expression |
| 111 | + 'field2' => 'REVERSE(t.field2)', // alias => db-expression |
| 112 | + 'field4' => 't.field2' // alias => db-expression |
| 113 | + ], $_GET)) |
| 114 | +->fetchRows(); |
| 115 | +``` |
| 116 | + |
| 117 | +*⚠ Any aliases specified in the search instructions but for which no DB expression has been defined will result in an exception. It is better that it will bang in such a case instead of just not working.* |
| 118 | + |
| 119 | +## Some examples |
| 120 | + |
| 121 | +```PHP |
| 122 | +$subSelect = function ($id) use ($mysql) { |
| 123 | + return $mysql->select() |
| 124 | + ->field('t.id') |
| 125 | + ->from('t', 'table') |
| 126 | + ->where('t.foreign_id=?', $id); |
| 127 | +}; |
| 128 | + |
| 129 | +$select = $mysql->select() |
| 130 | +->field('COUNT(*)', 'customer_count') |
| 131 | +->from('t1', 't#test1') |
| 132 | +->joinInner('t2', 't#test2', 't2.test_id = t1.id AND t2.field1 = ?', 123) |
| 133 | +->joinLeft('t3', 't#test3', 't3.test_id = t1.id') |
| 134 | +->joinRight('t4', 't#test4', 't4.test_id = t1.id') |
| 135 | +->joinRight('t5', $subSelect(10), 't5.test_id = t1.id') |
| 136 | +->orderBy('t1.field1') |
| 137 | +->orderBy('t1.field2', 'DESC') |
| 138 | +->limit(100) |
| 139 | +->offset(50); |
| 140 | +``` |
| 141 | + |
| 142 | +```PHP |
| 143 | +if($contition === true) { |
| 144 | + $select->where('t1.somefield = ?', $someValue); |
| 145 | +} |
| 146 | +``` |
| 147 | + |
| 148 | +```PHP |
| 149 | +$rows = $select->fetchRows(); |
| 150 | +foreach($rows as $row) { |
| 151 | + print_r($row); |
| 152 | +} |
| 153 | +``` |
| 154 | + |
| 155 | +## Complex select |
| 156 | + |
| 157 | +```php |
| 158 | +$dateStart = '2016-05-01'; |
| 159 | +$dateEnd = '2016-05-31'; |
| 160 | + |
| 161 | +$tableA = $db->select() |
| 162 | +->field('a.field1') |
| 163 | +->field('a.field2') |
| 164 | +->from('a', 'table_a') |
| 165 | +->where('a.date BETWEEN ? AND ?', $dateStart, $dateEnd); |
| 166 | + |
| 167 | +$tableB = $db->select() |
| 168 | +->field('b.field1') |
| 169 | +->field('b.field2') |
| 170 | +->from('b', 'table_b') |
| 171 | +->where('b.date BETWEEN ? AND ?', $dateStart, $dateEnd); |
| 172 | + |
| 173 | +$tableC = $db->select() |
| 174 | +->field('t.field1') |
| 175 | +->field('t.field2') |
| 176 | +->from('t', 'table_c') |
| 177 | +->where('t.date BETWEEN ? AND ?', $dateStart, $dateEnd); |
| 178 | + |
| 179 | +echo $db->select() |
| 180 | +->from('t', |
| 181 | + $db->select() |
| 182 | + ->field('a.field1') |
| 183 | + ->field('COALESCE(b.field2, a.field2)', 'field2') |
| 184 | + ->from('a', $tableA) |
| 185 | + ->joinLeft('b', $tableB, 'b.id=a.id') |
| 186 | + ->where('NOT ISNULL(a.field1)') |
| 187 | + ->union($tableC) |
| 188 | +); |
| 189 | +``` |
| 190 | + |
| 191 | +[Back](../README.md) |
| 192 | + |
0 commit comments