Задча написать SQL запрос, который бы возвращал точно такой вывод:
id|
---
1 |
2 |
3 |
5 |
Представьте, что в БД нет ни одной таблицы, и создавать их нельзя.
mysql> SELECT 1 id UNION SELECT 2 id UNION SELECT 3 id UNION SELECT 5 id;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 5 |
+----+
4 rows in set (0,00 sec)
Существует ли более элегантное решение?
В MySQL единственный вариант (Алиас нужен только у первого числа):
select 1 ID union select 2 union select 3 union select 5
Самый красивый (для малого количества чисел) вариант можно написать в MS-SQL и Postrgess:
select * from (values (1),(2),(3),(5)) as t(id)
Oracle (С использованием системного типа в качестве коллекции):
select column_value ID from table(sys.odcinumberlist(1,2,3,5))
Если чисел значительно больше и они идут просто подряд, то почти универсальный (Из широко распространенных СУБД НЕ работает только в MySQL):
with Q as (
select 1 ID
union all
select ID+1 from Q where ID<5
) select * from Q
Самый лаконичный (IMHO) вариант для большого количества чисел подряд в Oracle:
select rownum id from DUAL connect by rownum<6
ЕщёВ Oracle можно воспользоваться XQuery последовательностью:
select to_number(column_value) id from xmlTable ('1 to 3, 5')
/
ID
----------
1
2
3
5
👉 Пишите свое решение в комментариях👇
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥6❤4
🔥 Подборка каналов для разработчиков
⭐️ Нейронные сети
@vistehno - chatgpt ведет блог, решает любые задачи и отвечает на любые ваши вопросы.
@aigen - сети для генерации картинок. видео, музыки и многого другого.
@neural – погружение в нейросети.
🖥 Machine learning
@ai_ml – погружение в нейросети, ai, Chatgpt, midjourney, машинное обучение.
@datasc - дата сайнс обучаем самой востребованной профессии
@machinelearning_ru – машинное обучении на русском от новичка до профессионала.
@machinelearning_interview – подготовка к собеседованию.
@datascienceiot – бесплатные книги Machine learning
@ArtificialIntelligencedl – канал о искусственном интеллекте
@machinee_learning – чат о машинном обучении
@datascienceml_jobs - работа ds, ml
@Machinelearning_Jobs - чат работы мл
🖥 SQL базы данных
@sqlhub - Повышение эффективности кода с грамотным использованием бд.
@chat_sql - чат изучения бд.
🖥 Python
@pythonl - главный канал самого популярного языка программирования.
@pro_python_code – учим python с ментором.
@python_job_interview – подготовка к Python собеседованию.
@python_testit - проверочные тесты на python
@pythonlbooks - современные книги Python
@python_djangojobs - работа для Python программистов
@python_django_work - чат обсуждения вакансий
🖥 Javascript / front
@react_tg - - 40,14% разработчиков сайтов использовали React в 2022 году - это самая популярная библиотека для создания сайтов.
@javascript -канал для JS и FrontEnd разработчиков. Лучшие практики и примеры кода. Туториалы и фишки JS
@Js Tests - каверзные тесты JS
@hashdev - погружение в web разработку.
@javascriptjobjs - отборные вакансии и работа FrontEnd.
@jsspeak - чат поиска FrontEnd работы.
🖥 Java
@javatg - выучить Java с senior разработчиком по профессиональной методике.
@javachats - чат для ответов на вопросы по Java
@java_library - библиотека книг Java
@android_its - Android разработка
@java_quizes - тесты Java
@Java_workit - работа Java
@progersit - шпаргалки ит
👣 Golang
@Golang_google - восхитительный язык от Google, мощный и перспективный.
@golang_interview - вопросы и ответы с собеседований по Go. Для всех уровней разработчиков.
@golangtests - интересные тесты и задачи GO
@golangl - чат изучающих Go
@GolangJobsit - отборные вакансии и работа GO
@golang_jobsgo - чат для ищущих работу.
@golang_books - полезные книги Golang
@golang_speak - обсуждение языка Go
🖥 Linux
@linux -топ фишки, гайды, уроки по работе с Linux.
@linux chat - чат linux для обучения и помощи.
@linux_read - бесплатные книги linux
👷♂️ IT работа
@hr_itwork -кураторский список актуальных ит-ваканнсии
🤡It memes
@memes_prog - ит-мемы
⚙️ Rust
@rust_code - Rust избавлен от болевых точек, которые есть во многих современных яп
@rust_chats - чат rust
#️⃣ c# c++
C# - объединяет лучшие идеи современных языков программирования
@csharp_cplus чат
С++ - Универсальность. Возможно, этот главный плюс C++.
📓 Книги
@programming_books_it - большая библиотека. программиста
@datascienceiot -ds книги
@pythonlbooks - python библиотека.
@golang_books - книги Golang
@frontendbooksit - front книги
@progersit - ит-шпаргалки
@linux_read - Linux books
@java_library - Java books
🖥 Github
@github_code - лучшие проекты с github
@bigdatai - инструменты по работе с данными
🖥 Devops
Devops - специалист общего профиля, которому нужны обширные знания в области разработки.
📢 English for coders
@english_forprogrammers - Английский для программистов
@vistehno - chatgpt ведет блог, решает любые задачи и отвечает на любые ваши вопросы.
@aigen - сети для генерации картинок. видео, музыки и многого другого.
@neural – погружение в нейросети.
@ai_ml – погружение в нейросети, ai, Chatgpt, midjourney, машинное обучение.
@datasc - дата сайнс обучаем самой востребованной профессии
@machinelearning_ru – машинное обучении на русском от новичка до профессионала.
@machinelearning_interview – подготовка к собеседованию.
@datascienceiot – бесплатные книги Machine learning
@ArtificialIntelligencedl – канал о искусственном интеллекте
@machinee_learning – чат о машинном обучении
@datascienceml_jobs - работа ds, ml
@Machinelearning_Jobs - чат работы мл
@sqlhub - Повышение эффективности кода с грамотным использованием бд.
@chat_sql - чат изучения бд.
@pythonl - главный канал самого популярного языка программирования.
@pro_python_code – учим python с ментором.
@python_job_interview – подготовка к Python собеседованию.
@python_testit - проверочные тесты на python
@pythonlbooks - современные книги Python
@python_djangojobs - работа для Python программистов
@python_django_work - чат обсуждения вакансий
@react_tg - - 40,14% разработчиков сайтов использовали React в 2022 году - это самая популярная библиотека для создания сайтов.
@javascript -канал для JS и FrontEnd разработчиков. Лучшие практики и примеры кода. Туториалы и фишки JS
@Js Tests - каверзные тесты JS
@hashdev - погружение в web разработку.
@javascriptjobjs - отборные вакансии и работа FrontEnd.
@jsspeak - чат поиска FrontEnd работы.
@javatg - выучить Java с senior разработчиком по профессиональной методике.
@javachats - чат для ответов на вопросы по Java
@java_library - библиотека книг Java
@android_its - Android разработка
@java_quizes - тесты Java
@Java_workit - работа Java
@progersit - шпаргалки ит
@Golang_google - восхитительный язык от Google, мощный и перспективный.
@golang_interview - вопросы и ответы с собеседований по Go. Для всех уровней разработчиков.
@golangtests - интересные тесты и задачи GO
@golangl - чат изучающих Go
@GolangJobsit - отборные вакансии и работа GO
@golang_jobsgo - чат для ищущих работу.
@golang_books - полезные книги Golang
@golang_speak - обсуждение языка Go
@linux -топ фишки, гайды, уроки по работе с Linux.
@linux chat - чат linux для обучения и помощи.
@linux_read - бесплатные книги linux
👷♂️ IT работа
@hr_itwork -кураторский список актуальных ит-ваканнсии
🤡It memes
@memes_prog - ит-мемы
⚙️ Rust
@rust_code - Rust избавлен от болевых точек, которые есть во многих современных яп
@rust_chats - чат rust
#️⃣ c# c++
C# - объединяет лучшие идеи современных языков программирования
@csharp_cplus чат
С++ - Универсальность. Возможно, этот главный плюс C++.
📓 Книги
@programming_books_it - большая библиотека. программиста
@datascienceiot -ds книги
@pythonlbooks - python библиотека.
@golang_books - книги Golang
@frontendbooksit - front книги
@progersit - ит-шпаргалки
@linux_read - Linux books
@java_library - Java books
@github_code - лучшие проекты с github
@bigdatai - инструменты по работе с данными
Devops - специалист общего профиля, которому нужны обширные знания в области разработки.
@english_forprogrammers - Английский для программистов
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥14❤13👏2🥰1
Нужно ли отправлять изменения в БД одной транзакцией, или каждый INSERT, UPDATE, DELETE лучше выполнять отдельной транзакцией? Что лучше при выполнении 10 несвязанных запросов (не нужно откатывать предыдущий запрос при ошибке последующего), отправить их одной транзакцией, или каждый по отдельности? Какой вариант лучше для производительности приложения и субд?
В общем случае ни первый ни второй вариант не являются оптимальными с точки зрения производительности.
Если нужно удалить(вставить/поменять) действительно большое количество строк, в первом случае мы получаем большие расходы на открытие, закрытие большого количества транзакций.
Во втором случае имеем слишком огромную транзакцию, которая тоже под конец работы будет долго закрываться, да ещё и рискуем упасть, т.к. размеры транзакции ограничены(видел такую ошибку всего на нескольких миллионах строк).
Чтобы наглядно продемонстрируем, написал небольшой скрипт. MS SQL Server.
Кратко что он делает:
▪T_TABLE - таблица с данными
▪T_RESULT - таблица с результатами эксперимента
▪P_INSERT_ROWS @Count - вставляет в таблицу T_TABLE @Count строк
▪P_DALATE_ROWS @Count, @Pack - удаляет из таблицы
T_TABLE все строки в транзакциях по @Pack штук, и записывает затраченное время в таблицу T_RESULT.
Финальный скрипт запускает в цикле вставку 1 000 000 строк, и их удаления пачками по 1, 10 .. 1 000 000 штук. И затем выводит содержимое T_RESULT.
Скрипт:
USE tempdb;
GO
IF OBJECT_ID('P_INSERT_ROWS', 'P') IS NOT NULL DROP PROC P_INSERT_ROWS;
IF OBJECT_ID('P_DELETE_ROWS', 'P') IS NOT NULL DROP PROC P_DELETE_ROWS;
IF OBJECT_ID('T_TABLE', 'U') IS NOT NULL DROP TABLE T_TABLE;
IF OBJECT_ID('T_RESULT', 'U') IS NOT NULL DROP TABLE T_RESULT;
GO
CREATE TABLE T_TABLE (
id INT IDENTITY(1,1),
Number INT,
String NVARCHAR(4000)
)
CREATE INDEX IN_T_TABLE_NUMBER ON T_TABLE(Number ASC)
CREATE TABLE T_RESULT (
execute_time DATETIME,
Cnt INT,
Pack INT
)
GO
CREATE PROC P_INSERT_ROWS
@Count INT
AS
;WITH CTE AS(
SELECT 1 N UNION ALL SELECT N+1 FROM CTE WHERE N<@Count
)
INSERT T_TABLE
SELECT N, LEFT(REPLICATE(N, 100),4000)
FROM CTE
OPTION(MAXRECURSION 0)
GO
CREATE PROC P_DELETE_ROWS
@Count INT,
@Pack INT
AS
DECLARE @TTT DATETIME = GETDATE();
DECLARE @NumberStart INT = 1
WHILE @NumberStart < @Count
BEGIN
BEGIN TRAN;
DELETE FROM T_TABLE WHERE Number BETWEEN @NumberStart AND @NumberStart + @Pack - 1 OPTION(RECOMPILE);
COMMIT TRAN;
SET @NumberStart += @Pack;
END;
INSERT T_RESULT
SELECT GETDATE()-@TTT execute_time, @Count Cnt, @Pack Pack
GO
SET NOCOUNT ON;
DECLARE
@Count INT = 1000000,
@Pack INT = 1
WHILE @Pack <= @Count
BEGIN
EXEC P_INSERT_ROWS @Count
EXEC P_DELETE_ROWS @Count, @Pack
SET @Pack *= 10;
END
SELECT * FROM T_RESULT
GO
Содержимое T_RESULT:
execute_time Cnt Pack
1900-01-01 00:15:05.183 1000000 1
1900-01-01 00:01:56.003 1000000 10
1900-01-01 00:00:32.200 1000000 100
1900-01-01 00:00:22.370 1000000 1000
1900-01-01 00:00:21.940 1000000 10000
1900-01-01 00:00:22.663 1000000 100000
1900-01-01 00:01:10.327 1000000 1000000
Как видим, лучший результат по времени выполнения имеем, когда удаляется в одной транзакции пачками по 10000 штук, т.е. это намного эффективнее, чем удалять по одной записи в транзакции, и эффективнее, чем удалить все строки в одной транзакции. Эксперимент не строгий, запуски влияют друг на друга, но всё равно показательно.
UPD: На практике, транзакции в реальной жизни не часто бывают большими. Кроме запросов вида DELETE FROM T. В этом случае да, чаще всего если есть возможность обернуть несколько действий в одну транзакцию - лучше обернуть.
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤4🔥1
Имеются следующие таблицы:
Person(поля Nom и др.) - информация о людях,
Profit(поля ID, Source, Moneys) - источники дохода,
Have_d(поля Nom, ID и др.) - связь между людьми и их доходами.
Каждый человек может иметь несколько источников дохода. Необходимо вывести всю информацию о самом популярном источнике дохода.
То есть необходимо подсчитать количество включений всех видов доходов, выбрать максимальное и вывести полученное число вместе со всеми полями таблицы Profit, соответствующими полученному максимуму.
Решение:
select top 1 t1.*
from (select profit.source,count(*) as expr1
from profit, have_d
where profit.id = have_d.id
group by profit.source) as t1
order by expr1 desc
Вариант2:
select t1.*
from (select profit.*,count(*) as expr1
from profit, have_d
where profit.id = have_d.id
group by profit.id
order by expr1 desc) as t1
limit 1
👉 Это не оптимальное решение. Пишите свое решение в комментариях👇
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤1🔥1
Какой из следующих SQL запросов выберет первые 10% записей таблицы, отсортированные по колонке "sales" в порядке убывания?
Anonymous Quiz
26%
SELECT * FROM table WHERE sales > (SELECT MAX(sales) FROM t) * 0.1 ORDER BY sales DESC;
11%
SELECT * FROM table WHERE sales > (SELECT MIN(sales) FROM t) * 0.1 ORDER BY sales DESC LIMIT 10%;
12%
SELECT * FROM t WHERE sales > (SELECT AVG(sales) FROM t) * 0.1 ORDER BY sales DESC LIMIT 10;
51%
SELECT * FROM t ORDER BY sales DESC LIMIT 10%
🔥15👍9❤4
Покупки товара после 10 октября 2022 [Тестовое Альфа-банк]
#junior
Задание
Необходимо вывесть количество людей, которые покупали товар с
Столбцы в результате
count - столбец с посчитанным количеством людей
Важно: Названия столбцов должны в точности совпадать.
Пишите свое решение в комментариях👇
@sqlhub
#junior
Задание
Необходимо вывесть количество людей, которые покупали товар с
id = 5
после 10 октября 2022 (включительно).Столбцы в результате
count - столбец с посчитанным количеством людей
Важно: Названия столбцов должны в точности совпадать.
Пишите свое решение в комментариях👇
@sqlhub
❤8👍7🔥1
Каков лучший способ хранения двоичных данных в MySQL? Это вопрос, на который есть несколько ответов, в зависимости от ваших целей. Например, если вам нужно оптимизировать размер хранилища, вам, вероятно, потребуется использовать какой-либо алгоритм сжатия, который эффективно сжимает ваши данные. В моём случае мне действительно нужна высокая производительность, то есть максимально быстрое время отклика для извлечения большого двоичного объекта из MySQL.
Давайте отложим в сторону вопрос о том, подходит ли MySQL для хранения двоичных данных. Вопрос здесь будет заключаться в том, как хранить двоичные данные, чтобы считывание из БД происходило как можно быстрее?
Решением может быть использование сжатия данных. Однако это то, что требует сравнительного анализа, поскольку существует компромисс между использованием процессора для распаковки и скоростью сети. В этом тесте я собираюсь сравнить производительность между различными алгоритмами сжатия, сжатия с использованием самого MySQL и без использования сжатия вообще.
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤1🔥1
Вводные данные
Таблица со зданиями и координатами (в оригинальной таблице более 100 тыс. строк):
CREATE TABLE table1(
building_id int,
region varchar(55),
street varchar(55),
housenumber varchar(55),
pos_x float(100),
pos_y float(100)
);
INSERT ALL
INTO table1(building_id,region, street, housenumber, pos_x, pos_y ) VALUES(1, 'Moscow','Lenina', '1a', 45.45, 55.55 )
INTO table1(building_id,region, street, housenumber, pos_x, pos_y) VALUES(2, 'Spb','Mira', '20', 45.00, 55.00 )
INTO table1(building_id,region, street, housenumber, pos_x, pos_y) VALUES(3, 'Moscow','Lenina', '1a', 45.00, 55.00 )
INTO table1(building_id,region, street, housenumber, pos_x, pos_y) VALUES(4, 'Moscow', 'Lenina', '1a', 45.45, 55.55 )
SELECT * FROM dual;
Вывод
Building_ID region street housenumber pos_x pos_y
1 Moscow Lenina 1a 45.45 55.55
2 Spb Mira 20 45 55.55
3 Moscow Lenina 1a 45 55.55
4 Moscow Lenina 1a 45.45 55.55
Ожидаемый результат
Building_ID region street housenumber pos_x pos_y
1 Moscow Lenina 1a 45.45 55.55
4 Moscow Lenina 1a 45.45 55.55
Нужно вывести дубли по региону, улице, дому и координатам одновременно, т.е. должны остаться только
ID 1 и 4.
Для меня получилось проблемно, т.к. тип координат FLOAT
и они никак не хотят фильтроваться.С помощью HAVIG BY и EXISTS:
SELECT *
FROM table22 A
WHERE EXISTS (
SELECT COUNT(*)
FROM table22 t
WHERE a.region = t.region
AND a.street = t.street
AND a.housenumber = t.housenumber
AND a.pos_x = t.pos_x
AND a.pos_y = t.pos_y
HAVING COUNT(*) > 1
)
С помощью оконной фукнции
SELECT x.building_id, x.region, x.street, x.housenumber, x.pos_x, x.pos_y FROM (
SELECT
t.*
, COUNT(*) OVER(PARTITION BY t.street, t.region, t.housenumber, t.pos_x, t.pos_y ) cnt
FROM table22 t
) x
WHERE cnt > 1;
Пишите свое решение в комментариях👇
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥6❤2
Есть запрос №1:
WITH cte1 AS
(SELECT *,
ROW_NUMBER() OVER (ORDER BY column1) AS rn
FROM table)
SELECT column0
FROM cte1
WHERE rn = 1022;
есть запрос №2:
WITH cte1 AS
(SELECT column0,
ROW_NUMBER() OVER (ORDER BY column1) AS rn
FROM table)
SELECT column0
FROM cte1
WHERE rn = 1022;
PostgreSQL, в column0 нет NULL-ов, значения уникальны.
При использовании
SELECT * и SELECT column0
, получаем разные значения на rn 1022
(и не только на 1022). Сортировка в cte1 одна и та же, ничего не меняется, кроме количества колонок. Почему так происходит ? Это особенность SQL. Если явно не указана сортировка, то база данных может вернуть строки в любом порядке. Как ей захочется. И это может зависить не только от звездочки в запросе, но и просто от времени когда делается запрос.
Хотите избежать неоднозначности - указывайте сортировку в явном виде.
Проблема возникает из-за того, что сортировка по column1 в случае - неоднозначна т.е. в этом поле есть дубликаты и отсортировать по column1 можно разными способами, что БД и делает при разных запросах.
Вот пример:
column0 | column1
--------+---------
A | 1
B | 1
Проблема возникает из-за того, что сортировка по column1 в вашем случае неоднозначна т.е. в этом поле есть дубликаты и отсортировать по column1 можно разными способами, что БД и делает при разных запросах.
Вот пример:
column0 | column1
--------+---------
A | 1
B | 1
Если выполнить запрос из
CTE
, до любой порядок строк будет правильным и если мы выбираем, скажем, rn=1
то мы можем получить в результате и A и B.
Чтоб этого избежать нужно задавать сортировку по полям, которые однозначно задают порядок. Обычно достаточно включить последним (т.е. самым низкоприоритетным) полем в сортировке уникальное поле (например, первичный ключ), например:
SELECT column0,
ROW_NUMBER() OVER (ORDER BY column1, id) AS rn
FROM table
В этом случае порядок всегда будет определен однозначно, т.к. для записей с одинаковыми значениями column1
сортировка будет происходить по полю id.
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17❤4🔥1
hr.employees:
EMPLOYEE_ID FIRST_NAME LAST_NAME EMAIL PHONE_NUMBER HIRE_DATE JOB_ID SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
100 Steven King SKING 515.123.4567 17-JUN-03 AD_PRES 24000 - - 90
hr.departments:
DEPARTMENT_ID DEPARTMENT_NAME MANAGER_ID LOCATION_ID
10 Administration 200 1700
Задача: Путем соединения таблиц
HR.DEPARTMENTS и HR.EMPLOYEES
получить список департаментов, указав по каждому департаменту среднюю зарплату сотрудников и количество сотрудников, получающих комиссионную надбавку.select
d.department_id
, department_name
, d.manager_id
, d.location_id
from hr.departments d
left join hr.employees e on e.department_id = d.department_id
group by d.department_id
, department_name
, d.manager_id
, d.location_id
having min(e.salary) < 5000
Пишите свое решение в комментариях👇
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤3🔥3
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍6❤1😁1
Распространенные ошибки SQL в хранимых процедурах и запросах
Я не буду описывать совсем банальные вроде ошибки синтаксиса (talbe вместо table). В статье мы рассмотрим досадные ошибки sql server, которые снижают скорость нашей разработки.
📌 Читать
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥4❤1
import sqlite3
con = sqlite3.connect('BD88.db')
cursorObj = con.cursor()
cursorObj.execute('CREATE TABLE IF NOT EXISTS tabl (adr text)')
con.commit()
with open("2.txt", 'r', encoding="utf-8") as file:
for line in file.readlines():
s = line.strip()
cursorObj.execute("""INSERT INTO tabl (adr) VALUES (?);""", (s,))
con.commit()
Подробный гайд по работе с SQL lite на Python с примерами кода.
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤3😢2🔥1
Используйте процедуру
loop_execute()
для обработки строк в больших таблицах (тысячи и миллионы строк) с контролируемым временем блокировки строк на запись. Принцип работы — выполняет в цикле CTE DML запрос, который добавляет, обновляет или удаляет записи в таблице. В завершении каждого цикла изменения фиксируются (либо откатываются для целей тестирования, это настраивается). Автоматически адаптируется под нагрузку на БД. На реплику данные передаются постепенно небольшими порциями, а не одним огромным куском.
В процессе обработки показывает в psql консоли:
▪количество модифицированных и обработанных записей в таблице
▪сколько времени прошло, сколько примерно времени осталось до завершения, прогресс выполнения в процентах
Прогресс выполнения в процентах для работающего процесса отображается ещё в колонке pg_stat_activity.application_name!
Процедура не предназначена для выполнения в транзакции, т.к. сама делает много маленьких транзакций.
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤1🔥1🤔1
CTE. Обобщенное табличное выражение SQL и способы его использования
CTE, или Common Table Expressions — один из видов запросов в системах управления базами данных. На русском языке они называются обобщенными табличными выражениями. Результаты табличных выражений можно временно сохранять в памяти и обращаться к ним повторно.
Аналог CTE — временные таблицы, которые создаются только в рамках выполнения какой-либо операции и удаляются, как только становятся не нужны. Это позволяет упростить обращение к базе, сделать его быстрее и понятнее для разработчика. С помощью CTE код становится короче и яснее. Но табличные выражения отличаются от временных таблиц — мы рассмотрим различия ниже.
▪ Читать
@sqlhub
CTE, или Common Table Expressions — один из видов запросов в системах управления базами данных. На русском языке они называются обобщенными табличными выражениями. Результаты табличных выражений можно временно сохранять в памяти и обращаться к ним повторно.
Аналог CTE — временные таблицы, которые создаются только в рамках выполнения какой-либо операции и удаляются, как только становятся не нужны. Это позволяет упростить обращение к базе, сделать его быстрее и понятнее для разработчика. С помощью CTE код становится короче и яснее. Но табличные выражения отличаются от временных таблиц — мы рассмотрим различия ниже.
▪ Читать
@sqlhub
🔥11❤3👍3
Если вы хотите отфильтровать свои данные, чтобы найти релевантную информацию с помощь SQL запросов, используя датафрейм Pandas, вы можете воспользоваться встроенной функции 𝗾𝘂𝗲𝗿𝘆() .
Функция выполняет запросы на основе логических выражений, как если бы вы писали запрос на естественном языке!
В этой статье мы расскажем, как с помощью Pandas добиться на Python такого же результата, как в SQL-запросах.
▪ Статья
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥3❤1
Дано
Даны две таблицы
LongTable
и WideTable
:LongTable
:
+---------+--------+-----------------------+
| Name | key | value |
+---------+--------+-----------------------+
| Ivanov | FIO | Иванов Иван Иванович |
+---------+--------+-----------------------+
| Ivanov | Phone | +(7) 111-1111111 |
+---------+--------+-----------------------+
| Ivanov | Email | ivanov@ivanov.com |
+---------+--------+-----------------------+
| Petrov | FIO | Петров Петр Петрович |
+---------+--------+-----------------------+
| Petrov | Phone | +(7) 222-2222222 |
+---------+--------+-----------------------+
| Petrov | Email | petrov@petrov.com |
+---------+--------+-----------------------+
WideTable:
+---------+----------------------+------------------+-------------------+
| Name | FIO | Phone | Email |
+---------+----------------------+------------------+-------------------+
| Ivanov | Иванов Иван Иванович | +(7) 111-1111111 | ivanov@ivanov.com |
+---------+----------------------+------------------+-------------------+
| Petrov | Петров Петр Петрович | +(7) 222-2222222 | petrov@petrov.com |
+---------+----------------------+------------------+-------------------+
ЗаданиеКак из таблицы
LongTable
получить WideTable
?Примечание. Предполагается чтение таблицы один раз и отсутствие соединений.
Столбцы в результате
Name
fio
phone
email
Важно: Обратите внимание, что название столбцов в вашем ответе должно в точности совпадать с условием.
Сортировка
Результат отсортируйте по возрастанию поля
Name
.Пишите свое решение в комментариях👇
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17👍10❤2
Для сортировки по возрастанию используется следующая конструкция:
Anonymous Quiz
5%
GROUP BY имя_поля DESC
77%
ORDER BY имя_поля ASC
12%
ORDER BY имя_поля DESC
6%
GROUP BY имя_поля ASC
👍16😱9🔥6😁2❤1
Основная идея работы скрипта – генерация запросов с учетом различных параметров и последовательное их выполнение для вставки данных в существующую таблицу или выгрузка данных в файл.
Сама программа состоит из 3 частей:
1) Соединение c базой данных.
2)Определение варьируемых параметров.
3)Выполнение запросов к базе (структура построения запросов позволяет выполнять запросы последовательно или параллельно, что позволяет управлять скоростью загрузки/выгрузки данных с сервера).
Соединение с БД определяется фабрикой, в которой содержатся параметры соединения с определенным сервером и определены ссылки на классы для работы с БД.
db = DatabaseFactory().build('*наименование сервера*')
Сами объекты для работы с БД содержат 3 метода:
▪
collect
– запускает запрос с помощью метода read_sql библиотеки pandas и возвращает DataFrame, содержащий результат выполненного запроса;▪
execute
– запускает запросы типа CREATE, UPDATE, DELETE\TRUNCATE\DROP;▪
execute_man
y – используется в основном для загрузки данных внутрь БД. Сама загрузка производится с помощью BULK вставки.db.collect('select top 100 * from table')
db.execute('insert into table select * from another_table')
db. execute_many ('insert into from table (id, name, age) values (?,?,?)', [1,’Jhon’, 25])
Далее пользователь может задать параметры запроса с помощью метода
add_var
класса SqlContext
. Данный метод принимает 4 параметра: наименование колонки, значения данной переменной, условие (=, <=, >=, between и т.п.) и разделитель (под разделителем понимаются команды AND и OR).context = SqlContext()
context.add_var('col_name’, [1,2,3,4,5], separator='AND', condition='=')
context.add_var('col_name_1’, [[‘a’,’b’,’v’], [‘a1’,’b2’,’v3’],] , separator='AND', condition='in')
В случае определения нескольких параметров одновременно, в запросе они будут варьироваться по следующему правилу: сначала варьируются те параметры, которые были заданы в последнюю очередь. Если все вариации последнего параметра будут пройдены, то берутся следующее значения параметра выше и вновь перебираются все вариации последнего параметра. Так продолжается до тех пор, пока не переберутся все возможные комбинации заданных параметров.
После того, как мы определили варьируемые параметры необходимо задать сам sql запрос. Для этого создаем объект
SqlBuilder
и вызываем метод custom_sql
внутрь которого помещаем сам запрос:builder = SqlBuilder()
builder.custom_sql('''
INSERT INTO insertable_table
SELECT
*
FROM table
WHERE 1=1
AND col1 in (1, 2,10,98,34)
AND col2 = 9
AND col3 between ‘20200101’ and ‘20200201’
''')
или можно воспользоваться встроенными в объект методами для генерации sql (select, insert_into, create_table
и т.д.):builder = SqlBuilder()
builder.select([‘col1’, ‘col2’, ‘col3’]).from(‘table’)
Для запуска скрипта необходимо создать объект класса SqlGenerator, объекты SqlBuilder и SqlContext и с помощью цикла запустить обработку запроса (в качестве примера был взят вариант последовательного исполнения запроса):
generator = SqlGenerator(builder, context)
for sql in tqdm(generator.generate()):
t = time.time()
db.execute(sql)
print('Итоговое время работы запроса: ' + str(time.time()-t))
В итоге данный скрипт позволяет значительно сократить трудозатраты и время на выполнение рутинных запросов, чем я неоднократно пользовался в своей работе.
Весь исходный код опубликован на github.
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19🔥5❤1
SQL_big_cheatsheet.pdf
1.5 MB
🔥Доступ в Библиотеку бесплатных КНИГ, шпаргалок и лекций по базам данным.
@sqlhub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥6❤1