Научете се да работите със записи и повтарящи се полета
Винаги намирах SQL за разочароващ, защото не можех да съхранявам списъци по удобен начин. За щастие модерните хранилища за данни като BigQuery ни позволяват да използваме масиви и структури. Нека да видим как работи и да се научим да съхраняваме и отправяме заявки към вложени данни!
Създаване на масиви и структури
Масиви
Да приемем, че сте поръчали няколко артикула в местния супермаркет. Може да искате да съхраните поръчката си в таблица orders
. Искате един ред на поръчка, но всяка поръчка може да съдържа няколко елемента.
SELECT 1 AS order_id, ["soap", "sugar", "batteries"] AS order_items
Масивите по същество са списъци, които ви позволяват да съхранявате няколко резултата в едно поле. Нека запазим нашите резултати в таблица и да разгледаме схемата.
Можем да видим, че масивите не са тип данни, а режим: нашият масив от низове се третира като repeated
низ.
Структури
Ако искате да прегрупирате подобни полета заедно, структурите са правилният избор. Те са еквивалент на обекти или речници в други езици за програмиране и ви позволяват да съхранявате двойки ключове и стойности.
В нашия пример може да искаме да съхраним идентификатор, цена, име и количество за всеки продукт.
SELECT STRUCT( 1 AS id, "soap" AS name, 5.4 AS price, 2 AS quantity ) AS product
Нека запазим нашите продукти в друга таблица и да разгледаме схемата:
Тук нашето продуктово поле е от тип record
.
Масиви от структури
Тъкмо започваме да се забавляваме! Сега искате да имате списък на всички артикули, които сте закупили с всички подробности за продукта.
SELECT 1 AS order_id, [STRUCT( 1 AS id, "soap" AS name, 5.4 AS price, 2 AS quantity ) , STRUCT( 2 AS id, "sugar" AS name, 3.1 AS price, 1 AS quantity ), STRUCT( 3 AS id, "batteries" AS name, 2.8 AS price, 1 AS quantity ) ] AS order_items
Може би се досещате, нашето поле order_items е record
на режим repeated
.
Достъп до стойности
Вътрешни записи
Да предположим, че искаме да получим достъп до името на нашия продукт.
Това е доста лесно, просто трябва да добавим точка и да посочим ключа:
SELECT product.name FROM arrays_and_structs.products
Вътрешни масиви
Сега искаме да имаме достъп до всички отделни стойности на нашите продукти в нашите order_items:
Това става малко по-сложно, тъй като това е повтарящо се поле, ще трябва да го разместим.
BigQuery предоставя оператор UNNEST
, който създава таблица с един ред на повтарящо се поле. След това можем да JOIN
тази таблица с нашата първоначална таблица.
SELECT DISTINCT oi AS order_item FROM arrays_and_structs.orders_array INNER JOIN UNNEST(order_items) AS oi
И сега имаме нашия различен order_items
!
Има пряк път за това INNER JOIN
с невложено поле.
SELECT DISTINCT oi AS order_item FROM arrays_and_structs.orders_array, UNNEST(order_items) AS oi
Внимавайте, ако вашето вложено поле е празно, това вътрешно съединение ще изключи този ред. Представете си, че имаме тази таблица с подаръци, получени от хората за техния рожден ден:
Тъй като Том не получи никакъв подарък, ако разместим с помощта на вътрешно присъединяване, ето какво получаваме:
Нашият беден приятел Том не само не получи нищо, но и изчезна от нашата маса! Ако искаме да запазим всички, подарък или не, трябва да извършим ляво присъединяване.
SELECT name, gift FROM gifts LEFT JOIN UNNEST(gifts_received) AS gift
Този път Том е тук:
Вътрешни масиви от структури
Да предположим, че искаме да получим общата сума на всяка поръчка. Ще трябва да умножим количеството и цената на всеки артикул и след това да ги сумираме.
Просто комбинираме всичко, което научихме за достъп до структури и масиви и сумираме сумата:
SELECT order_id, SUM(order_item.price * order_item.quantity) AS order_amount FROM `arrays_and_structs.arrays_of_structs` LEFT JOIN UNNEST(order_items) order_item GROUP BY order_id
А ето и общата ни сума!
Ако искате да копаете по-нататък, вижте официалната документация за работа с масиви и вложени и повтарящи се полета.
И ако тази статия ви е харесала, последвайте ме за повече съдържание относно SQL и BigQuery, като тази статия за SQL JOINS: