PostgreSQL / INNER JOIN

INNER JOIN

Өгөгдлийн санд мэдээлэл олон хүснэгтэд тархан хадгалагддаг. Нэг query-д тэдгээрийг нэгтгэж харахад JOIN ашиглана. INNER JOIN бол хамгийн их хэрэглэгддэг, хамгийн ойлгомжтой join төрөл — хоёр хүснэгтэд хоёуланд нь байгаа бичлэгүүдийг л буцаана.

INNER JOIN гэж юу вэ?

Бодит жишээгээр ойлгоё. authors ба posts хоёр хүснэгт байна:

authors | id | нэр | |----|-----| | 1 | Болд | | 2 | Сарнай | | 3 | Ганбаяр |

posts | id | гарчиг | author_id | |----|--------|-----------| | 1 | SQL суурь | 1 | | 2 | JOIN тайлбар | 1 | | 3 | Index гэж юу вэ | 2 |

INNER JOIN нь author_id = authors.id таарах бичлэгүүдийг л буцаана. Ганбаяр нийтлэл нийтлээгүй тул үр дүнд орохгүй.

sql
SELECT posts.гарчиг, authors.нэр AS зохиогч
FROM posts
INNER JOIN authors ON posts.author_id = authors.id;
код
       гарчиг        | зохиогч
---------------------+---------
 SQL суурь           | Болд
 JOIN тайлбар        | Болд
 Index гэж юу вэ     | Сарнай

Үндсэн INNER JOIN хэлбэр

sql
SELECT баганууд
FROM хүснэгт1
INNER JOIN хүснэгт2 ON хүснэгт1.багана = хүснэгт2.багана;

INNER гэдэг үгийг орхиж болно — зөвхөн JOIN бичсэн ч адилхан ажилладаг:

sql
SELECT posts.гарчиг, authors.нэр
FROM posts
JOIN authors ON posts.author_id = authors.id;

Хүснэгтийн хоч нэр (alias)

Хүснэгтийн нэр урт байвал AS ашиглан богиносгоно — query илүү унших боломжтой болно:

sql
SELECT
    p.гарчиг,
    p.харагдсан,
    a.нэр AS зохиогч,
    a.имэйл
FROM posts AS p
JOIN authors AS a ON p.author_id = a.id
WHERE p.харагдсан > 100;

AS гэдэг үгийг ч орхиж болно (FROM posts p).

Олон хүснэгт JOIN хийх

Гурав ба түүнээс дээш хүснэгтийг дараалан join хийж болно:

sql
-- users → orders → order_items → products
SELECT
    u.нэр        AS хэрэглэгч,
    o.id         AS захиалга,
    p.нэр        AS бараа,
    oi.тоо,
    oi.үнэ
FROM users AS u
JOIN orders     AS o  ON o.user_id    = u.id
JOIN order_items AS oi ON oi.order_id  = o.id
JOIN products   AS p  ON p.id         = oi.product_id
WHERE u.id = 1;
код
 хэрэглэгч |  захиалга |     бараа       | тоо |     үнэ
-----------+-----------+-----------------+-----+-----------
 Болд       |         3 | Ухаалаг утас    |   1 | 1200000.00
 Болд       |         3 | Чихэвч          |   2 |   95000.00

ON нөхцөлд нэмэлт шүүлт

JOIN-ны ON нөхцөлд WHERE-тэй адил шүүлт нэмж болно:

sql
-- Зөвхөн нийтлэгдсэн нийтлэлүүдийг зохиогчтой нь унших
SELECT p.гарчиг, a.нэр
FROM posts AS p
JOIN authors AS a ON p.author_id = a.id
                  AND p.нийтлэгдсэн = TRUE;

Гэхдээ ихэнх тохиолдолд WHERE-д шүүлт тавих нь илүү тодорхой:

sql
SELECT p.гарчиг, a.нэр
FROM posts AS p
JOIN authors AS a ON p.author_id = a.id
WHERE p.нийтлэгдсэн = TRUE;

Нэгтгэх функцтэй хослуулах

JOIN ба GROUP BY-г хослуулан хүчирхэг тайлан гаргаж болно:

sql
-- Зохиогч тус бүрийн нийтлэлийн тоо ба нийт харагдалт
SELECT
    a.нэр AS зохиогч,
    COUNT(p.id)         AS нийтлэлийн_тоо,
    SUM(p.харагдсан)    AS нийт_харагдалт,
    MAX(p.харагдсан)    AS хамгийн_их_харагдалт
FROM authors AS a
JOIN posts AS p ON p.author_id = a.id
GROUP BY a.id, a.нэр
ORDER BY нийт_харагдалт DESC;
код
  зохиогч | нийтлэлийн_тоо | нийт_харагдалт | хамгийн_их_харагдалт
----------+----------------+----------------+---------------------
 Болд      |              2 |            470 |                 320
 Сарнай    |              1 |             85 |                  85

SELF JOIN — хүснэгт өөртэйгөө join

Хүснэгт өөртэйгөө join хийх тохиолдол байдаг — жишээ нь ажилтан ба тэдний менежер нэг хүснэгтэд байх үед:

sql
CREATE TABLE employees (
    id         BIGSERIAL PRIMARY KEY,
    нэр        TEXT NOT NULL,
    manager_id BIGINT REFERENCES employees(id)
);

-- Ажилтан ба тэдний менежерийн нэрийг хамт харах
SELECT
    e.нэр  AS ажилтан,
    m.нэр  AS менежер
FROM employees AS e
JOIN employees AS m ON e.manager_id = m.id;

Дараагийн хичээлд:

LEFT JOIN ба RIGHT JOIN-г сурна — нэг хүснэгтэд байгаагүй ч бүх бичлэгийг харуулах арга, мөн "таарахгүй мэдээллийг олох" маш хэрэгтэй техникийг ойлгоно.