This documentation outlines the structure for generating complex WHERE clauses using the group-centric array format. This approach ensures explicit control over logical connectors (AND/OR), making complex, nested queries robust and readable.
AND).'group' key) to force parentheses (...) and control the internal connector.?).connector vs. separatorThese two keys control linkage at different structural levels:
| Key | Purpose | Applies To |
|---|---|---|
connector |
Internal Glue: Dictates the operator used inside the parentheses. | The Group Array ('connector' is a sibling to 'group'). |
separator |
External Glue: Overrides the default operator used to join this item to the next item in the list. | Any Condition Array (simple or group). |
For a simple condition, the array contains the column name, comparator, and value.
| Key | Description | Required? |
|---|---|---|
name |
The column name. | Yes |
comparator |
The SQL operator (e.g., '=', '<', 'LIKE'). |
Yes |
value |
The value to compare against. | Yes |
separator |
(Optional) Overrides the default connector to link this condition to the next. | No |
separatorThe default connector is AND. The separator on condition A forces an OR link to condition B.
// SQL: WHERE ( (A = ?) OR (B = ?) AND (C = ?) )
$wheres = array(
// Condition A: (A = 1) is OR-ed to the next item
array(
'name' => 'A',
'comparator' => '=',
'value' => 1,
'separator' => 'OR',
),
// Condition B: (B = 2) is AND-ed to the next item (default)
array(
'name' => 'B',
'comparator' => '=',
'value' => 2,
),
// Condition C: (C = 3)
array(
'name' => 'C',
'comparator' => '=',
'value' => 3,
),
);
Use this structure to create parentheses (...) and control the internal logical operator using connector.
| Key | Description | Required? |
|---|---|---|
connector |
The operator used internally to join items within the 'group' array. |
Yes |
group |
The array of conditions (simple or nested groups) to be enclosed in parentheses. | Yes |
separator |
(Optional) Overrides the default connector to link this entire group to the next sibling item. | No |
connector)This group uses connector: 'OR' to find a keyword in any of the three fields.
// SQL: WHERE ( (CONCAT(...) LIKE ?) OR (u.username LIKE ?) OR (u.email LIKE ?) )
$wheres = array(
// Single item which is a group
array(
'connector' => 'OR', // <-- Internal Glue
'group' => array(
array('name' => "CONCAT(u.first_name, ' ', u.last_name)", 'comparator' => 'LIKE', 'value' => "%{$keyword}%"),
array('name' => 'u.username', 'comparator' => 'LIKE', 'value' => "%{$keyword}%"),
array('name' => 'u.email', 'comparator' => 'LIKE', 'value' => "%{$keyword}%"),
),
),
);
This structure ensures correct friend request deletion regardless of direction:
WHERE ( (A->B AND type) OR (B->A AND type) )
$from = 10;
$to = 20;
$wheres = array(
// OUTER GROUP: Forces OR between the two directional checks below
array(
'connector' => 'OR',
'group' => array(
// DIRECTION 1 GROUP: (relation_from = A AND relation_to = B AND type = request)
array(
'connector' => 'AND', // Internal logic is AND
'group' => array(
array('name' => 'relation_from', 'comparator' => '=', 'value' => $from),
array('name' => 'relation_to', 'comparator' => '=', 'value' => $to),
array('name' => 'type', 'comparator' => '=', 'value' => 'friend:request'),
),
),
// DIRECTION 2 GROUP: (relation_from = B AND relation_to = A AND type = request)
// This entire group is OR-ed with the first group because of the parent's 'connector' => 'OR'
array(
'connector' => 'AND', // Internal logic is AND
'group' => array(
array('name' => 'relation_from', 'comparator' => '=', 'value' => $to),
array('name' => 'relation_to', 'comparator' => '=', 'value' => $from),
array('name' => 'type', 'comparator' => '=', 'value' => 'friend:request'),
),
),
),
),
);
$wheres = array(
// Condition 1: Use separator to force the OR link
array(
'name' => 'a.message_to',
'comparator' => '=',
'value' => $guid,
'separator' => 'OR', // <-- Overrides the default AND
),
// Condition 2: Linked by the previous OR
array(
'name' => 'a.message_from',
'comparator' => '=',
'value' => $guid,
),
);
$wheres = array(
// Outer Group: Uses 'OR' to join the two conditions
array(
'connector' => 'OR', // <-- Explicitly sets the internal glue to OR
'group' => array(
// Condition 1: a.message_to = $guid
array('name' => 'a.message_to', 'comparator' => '=', 'value' => $guid),
// Condition 2: a.message_from = $guid
array('name' => 'a.message_from', 'comparator' => '=', 'value' => $guid),
),
),
);
We essentially defined the internal versus external linkage rules:
| Linkage | Key Used | Where It Applies | Purpose |
|---|---|---|---|
| Internal (Glue inside parentheses) | connector |
On the Group Array itself. | Dictates the logical operator (AND/OR) between the conditions within that group. |
| External (Glue between items) | separator |
On a Simple Condition or a Group Array. | Dictates the logical operator (AND/OR) used to join that condition/group to the next sibling item in the array. |
connector is for Internal Group Logic (Parentheses Glue)When you see a group array, the connector defines the default glue for all the items inside that group.
array(
'connector' => 'OR', // <-- This is the glue
'group' => array(
// ITEM A --[OR]-- ITEM B --[OR]-- ITEM C
),
)
separator is for External Item Logic (Sibling Glue)The separator is placed on the item that just finished to change the default operator used to connect it to the next item.
// Assuming default is 'AND'
array(
// ITEM 1
array( 'name' => 'X', 'value' => 1, 'separator' => 'OR' ), // <-- ITEM 1 is linked to ITEM 2 with OR
// ITEM 2
array( 'name' => 'Y', 'value' => 2 ), // <-- ITEM 2 is linked to ITEM 3 with AND (default)
// ITEM 3
array( 'name' => 'Z', 'value' => 3 ),
)
This documentation provides a detailed structure for building dynamic SQL queries using a group-centric array format. It offers flexibility for controlling logical connectors (AND/OR) and ensures clarity when constructing complex queries.