join: inner, right, left - orm d7

возьмем таблицы-примеры и разберем разницу join: inner, right, left

используемые нэймспейсы
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
IDNAMEEMAILCITY
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
IDUSER_IDPRODUCTPRICESTATUS
1011Ноутбук50000completed
1021Мышь1500pending
1032Клавиатура3000completed
1044Монитор25000completed
1055Наушники2000cancelled
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 (можно не указывать, это по умолчанию)
        )
    ]
]);
NAMEPRODUCTPRICE
Иван ПетровНоутбук50000
Иван ПетровМышь1500
Мария СидороваКлавиатура3000
Алексей СмирновNULLNULL


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
        )
    ] ]);
NAMEPRODUCTPRICE
Иван ПетровНоутбук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]  
        )
    ]
]);
NAMEPRODUCTPRICE
Иван ПетровНоутбук50000
Иван ПетровМышь1500
Мария СидороваКлавиатура3000