возьмем таблицы-примеры и разберем разницу join: inner, right, left
используемые нэймспейсы
USERS
ORDERS
LEFT JOIN (по умолчанию в Битрикс) - все из левой таблицы
RIGHT JOIN - все из правой таблицы
INNER JOIN - только совпадения
используемые нэймспейсы
use Bitrix\Main\Entity\ReferenceField; use Bitrix\Main\ORM\Data\DataManager; use Bitrix\Main\ORM\Fields\IntegerField; use Bitrix\Main\ORM\Fields\StringField; use Bitrix\Main\ORM\Query\Join; |
USERS
| ID | NAME | CITY | |
|---|---|---|---|
| 1 | Иван Петров | ivan@mail.ru | Москва |
| 2 | Мария Сидорова | maria@mail.ru | Санкт-Петербург |
| 3 | Алексей Смирнов | alex@mail.ru | Новосибирск |
class UsersTable extends DataManager{
public static function getTableName()
{
return 'users';
}
public static function getMap()
{
return [
new IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
new StringField('NAME'),
new StringField('EMAIL'),
new StringField('CITY'),
];
}
} |
ORDERS
| ID | USER_ID | PRODUCT | PRICE | STATUS |
|---|---|---|---|---|
| 101 | 1 | Ноутбук | 50000 | completed |
| 102 | 1 | Мышь | 1500 | pending |
| 103 | 2 | Клавиатура | 3000 | completed |
| 104 | 4 | Монитор | 25000 | completed |
| 105 | 5 | Наушники | 2000 | cancelled |
class OrdersTable extends DataManager
{
public static function getTableName()
{
return 'orders';
}
public static function getMap()
{
return [
new IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
new IntegerField('USER_ID'),
new StringField('PRODUCT'),
new IntegerField('PRICE'),
new StringField('STATUS'),
];
}
} |
LEFT JOIN (по умолчанию в Битрикс) - все из левой таблицы
SELECT USERS.NAME, ORDERS.PRODUCT, ORDERS.PRICE FROM USERS LEFT JOIN ORDERS ON USERS.ID = ORDERS.USER_ID |
$result = UsersTable::getList([
'select' => ['NAME', 'PRODUCT' => 'ORDER.PRODUCT', 'PRICE' => 'ORDER.PRICE'],
'runtime' => [
new ReferenceField(
'ORDER',
OrdersTable::class,
Join::on('this.ID', 'ref.USER_ID'),
['join_type' => Join::TYPE_LEFT] // LEFT JOIN (можно не указывать, это по умолчанию)
)
]
]); |
| NAME | PRODUCT | PRICE |
|---|---|---|
| Иван Петров | Ноутбук | 50000 |
| Иван Петров | Мышь | 1500 |
| Мария Сидорова | Клавиатура | 3000 |
| Алексей Смирнов | NULL | NULL |
RIGHT JOIN - все из правой таблицы
SELECT USERS.NAME, ORDERS.PRODUCT, ORDERS.PRICEFROM USERS RIGHT JOIN ORDERS ON USERS.ID = ORDERS.USER_ID |
$result = OrdersTable::getList([
'select' => ['NAME' => 'USER.NAME', 'PRODUCT', 'PRICE'],
'runtime' => [
new ReferenceField(
'USER',
UsersTable::class,
Join::on('this.USER_ID', 'ref.ID'),
['join_type' => Join::TYPE_LEFT] // LEFT от Orders = RIGHT от Users
)
] ]); |
| NAME | PRODUCT | PRICE |
|---|---|---|
| Иван Петров | Ноутбук | 50000 |
| Иван Петров | Мышь | 1500 |
| Мария Сидорова | Клавиатура | 3000 |
| NULL | Монитор | 25000 |
| NULL | Наушники | 2000 |
INNER JOIN - только совпадения
SELECT USERS.NAME, ORDERS.PRODUCT, ORDERS.PRICE FROM USERS INNER JOIN ORDERS ON USERS.ID = ORDERS.USER_ID |
$result = UsersTable::getList([
'select' => ['NAME', 'PRODUCT' => 'ORDER.PRODUCT', 'PRICE' => 'ORDER.PRICE'],
'runtime' => [
new ReferenceField(
'ORDER',
OrdersTable::class,
Join::on('this.ID', 'ref.USER_ID'),
['join_type' => Join::TYPE_INNER]
)
]
]); |
| NAME | PRODUCT | PRICE |
|---|---|---|
| Иван Петров | Ноутбук | 50000 |
| Иван Петров | Мышь | 1500 |
| Мария Сидорова | Клавиатура | 3000 |