Всем хорошей пятницы!
Действительно ли, что:
Oracle запрос SQL, использующий условие EXISTS очень неэффективен, так как подзапрос перезапускается для каждой строки в таблице внешнего запроса.
Есть более эффективные способы написания большинства запросов, которые бы не использовали условие EXISTS.
Ответ:
Для решения каждой задачи есть свои эффективные методы. Если EXISTS применяется в основном запросе выборки из небольшой таблицы для проверки данных в большой таблице, и если выборка из большой таблицы будет вестись по индексам, то его использование будет очень эффективно. Вот пример:
В таблице клиентов не более 1000 строк.
В таблице PAYMENTS миллион строк и таблица проиндексована по столбцу CLIENT_ID.
Нужно выбрать клиентов, по которым была хотя бы одна оплата.
SELECT *
FROM CLIENTS
WHERE EXISTS (SELECT 1 FROM PAYMENTS WHERE PAYMENTS.CLIENT_ID = CLIENTS.CLIENT_ID)
По таблице CLIENTS мы видим полный перебор строк (TABLE ACCESS FULL), но с проверкой есть ли платеж по клиенту. Запрос, отбирая клиентов, проверит есть ли в таблице PAYMENTS хотя бы одна строчка с таким CLIENT_ID. Хотя бы одна. И, так как на таблицу PAYMENTS есть индекс для выборки по столбцу CLIENT_ID, то таблица PAYMENTS вообще не будет читаться! Согласно приведённому запросу нам от неё не нужны данные. Нужно просто проверить есть ли строчка, где бы в столбце CLIENT_ID было бы конкретное значение. СУБД посмотрит в индекс и сразу поймёт есть ли строчка с таким то значением CLIENT_ID. Самого чтения миллионной таблицы не будет.
Многие СУБД, при правильной их настройке, хранят индексы постоянно используемых таблиц в оперативной памяти.
Стоит, всё же, заметить, что при использовании EXISTS или других подзапросов в транзакциях в некоторых СУБД могут быть проблемы.
Расскажу об этом дополнительно!
Действительно ли, что:
Oracle запрос SQL, использующий условие EXISTS очень неэффективен, так как подзапрос перезапускается для каждой строки в таблице внешнего запроса.
Есть более эффективные способы написания большинства запросов, которые бы не использовали условие EXISTS.
Ответ:
Для решения каждой задачи есть свои эффективные методы. Если EXISTS применяется в основном запросе выборки из небольшой таблицы для проверки данных в большой таблице, и если выборка из большой таблицы будет вестись по индексам, то его использование будет очень эффективно. Вот пример:
В таблице клиентов не более 1000 строк.
В таблице PAYMENTS миллион строк и таблица проиндексована по столбцу CLIENT_ID.
Нужно выбрать клиентов, по которым была хотя бы одна оплата.
SELECT *
FROM CLIENTS
WHERE EXISTS (SELECT 1 FROM PAYMENTS WHERE PAYMENTS.CLIENT_ID = CLIENTS.CLIENT_ID)
По таблице CLIENTS мы видим полный перебор строк (TABLE ACCESS FULL), но с проверкой есть ли платеж по клиенту. Запрос, отбирая клиентов, проверит есть ли в таблице PAYMENTS хотя бы одна строчка с таким CLIENT_ID. Хотя бы одна. И, так как на таблицу PAYMENTS есть индекс для выборки по столбцу CLIENT_ID, то таблица PAYMENTS вообще не будет читаться! Согласно приведённому запросу нам от неё не нужны данные. Нужно просто проверить есть ли строчка, где бы в столбце CLIENT_ID было бы конкретное значение. СУБД посмотрит в индекс и сразу поймёт есть ли строчка с таким то значением CLIENT_ID. Самого чтения миллионной таблицы не будет.
Многие СУБД, при правильной их настройке, хранят индексы постоянно используемых таблиц в оперативной памяти.
Стоит, всё же, заметить, что при использовании EXISTS или других подзапросов в транзакциях в некоторых СУБД могут быть проблемы.
Расскажу об этом дополнительно!
👍9
Друзья, всем добрый день!
Очередная задача по SQL!
В базе данных есть две таблицы CODES и CODES2, в каждой из которых есть столбец CODE. В таблицах CODES и CODES2 всего по три строки. В первой строке обеих таблиц в столбце CODE - значение: 1, во второй строке значение тоже 1 и в третьей строке - NULL.
Очередная задача по SQL!
В базе данных есть две таблицы CODES и CODES2, в каждой из которых есть столбец CODE. В таблицах CODES и CODES2 всего по три строки. В первой строке обеих таблиц в столбце CODE - значение: 1, во второй строке значение тоже 1 и в третьей строке - NULL.
👍1
Сколько строк вернёт следующий запрос:
SELECT * FROM CODES JOIN CODES2 ON CODES.CODE = CODES2.CODE
SELECT * FROM CODES JOIN CODES2 ON CODES.CODE = CODES2.CODE
Anonymous Quiz
7%
0
52%
2
38%
4
4%
8
❤4👍3👎2
Друзья, всем отличной пятницы!
На следующей неделе начинаем интенсив SQL, PostgreSQL!
У нас будет:
10 насыщенных онлайн занятий (с записью эфира);
Много совместной работы в режиме онлайн! Будет много практики! Готовимся работать, не просто слушать:)
Закрытая группа Телеграм с записями наших встреч и кратким конспектом! Здесь же я буду отвечать и на все вопросы по самостоятельным задачам (они тоже будут, работа один-на-один с базой данных обязательна).
Сертификат по окончанию он-лайн курса! И помощь в составлении резюме если потребуется!
Подробнее:
https://prime-soft.biz/courses/postgresql
На следующей неделе начинаем интенсив SQL, PostgreSQL!
У нас будет:
10 насыщенных онлайн занятий (с записью эфира);
Много совместной работы в режиме онлайн! Будет много практики! Готовимся работать, не просто слушать:)
Закрытая группа Телеграм с записями наших встреч и кратким конспектом! Здесь же я буду отвечать и на все вопросы по самостоятельным задачам (они тоже будут, работа один-на-один с базой данных обязательна).
Сертификат по окончанию он-лайн курса! И помощь в составлении резюме если потребуется!
Подробнее:
https://prime-soft.biz/courses/postgresql
prime-soft.biz
Prime | Курс SQL, PostgreSql
Уроки и курсы SQL, PostgreSQL, Базы данных.
👍2🔥2
Всем доброго понедельника!
Надеюсь, неделя началась отлично, или, по крайней мере, не плохо☺️
Предлашаю небольшую задачу по SQL, похожую на одну из тех, что мы с Вами уже решали.
Надеюсь, неделя началась отлично, или, по крайней мере, не плохо☺️
Предлашаю небольшую задачу по SQL, похожую на одну из тех, что мы с Вами уже решали.
❤2
В таблице INVOICES две строки. В первой строке в столбце QTY число 25, во второй строке в этом же столбце лежит NULL.
Каким будет результат запроса: SELECT MIN(QTY) FROM INVOICES
Каким будет результат запроса: SELECT MIN(QTY) FROM INVOICES
Anonymous Quiz
9%
Null
5%
0
1%
2
79%
25
0%
27
6%
Выполнение запроса приведёт к SQL ошибке
👍2
В таблице CLIENTS три строки:
ID NAME
1 АО "Проблемы и решения"
2 АО "Решения без проблем"
3 ИП "Иванов Иван Иванович"
В таблице INVOICES две строки:
ID ID_CLIENT DATE_INV
1 1 03.09.2024
2 1 03.09.2024
ID NAME
1 АО "Проблемы и решения"
2 АО "Решения без проблем"
3 ИП "Иванов Иван Иванович"
В таблице INVOICES две строки:
ID ID_CLIENT DATE_INV
1 1 03.09.2024
2 1 03.09.2024
Какое количество строк вернёт запрос SELECT * FROM CLIENTS WHERE EXISTS (SELECT COUNT(*) FROM INVOICES WHERE ID_CLIENT = CLIENTS.ID)
Anonymous Quiz
11%
0
47%
1
24%
2
16%
3
2%
4
1%
6
👍9👎9🦄3
Обучение на ошибках (особенно на своих 😀) - один из самых эффективных методов обучения!
Здесь нужно было заметить неправильное использование EXISTS.
Оператор EXISTS используют для проверки того, возвращается ли что-то подзапросом, указанным в скобках. Как правило, в скобках для оператора EXISTS/NOT EXISTS пишут:
SELECT *
или:
SELECT 1
В задаче выше нарочно допущена ошибка (в EXISTS нарочно написал SELECT COUNT).
SELECT COUNT всегда будет возвращать данные. Написанный в скобочках подзапрос всегда будет возвращать количество, хоть и иногда 0. Но данные-то есть. Ноль - это тоже данные. Поэтому EXISTS будет давать TRUE для каждой из трех строчек основного запроса.
И еще немного по теме COUNT напомню: COUNT всегда возвращает значение. Никогда не возвращает NULL. Если по условиям WHERE (под)запроса не будет подходящих данных, то COUNT вернёт 0, не NULL.
Здесь нужно было заметить неправильное использование EXISTS.
Оператор EXISTS используют для проверки того, возвращается ли что-то подзапросом, указанным в скобках. Как правило, в скобках для оператора EXISTS/NOT EXISTS пишут:
SELECT *
или:
SELECT 1
В задаче выше нарочно допущена ошибка (в EXISTS нарочно написал SELECT COUNT).
SELECT COUNT всегда будет возвращать данные. Написанный в скобочках подзапрос всегда будет возвращать количество, хоть и иногда 0. Но данные-то есть. Ноль - это тоже данные. Поэтому EXISTS будет давать TRUE для каждой из трех строчек основного запроса.
И еще немного по теме COUNT напомню: COUNT всегда возвращает значение. Никогда не возвращает NULL. Если по условиям WHERE (под)запроса не будет подходящих данных, то COUNT вернёт 0, не NULL.
👍29❤2🤯2👎1👾1
В таблице DOCUMENTS четыре строки. В поле DOC_TYPE в первых двух строках число 1, в двух других строках число 2. Запрос SELECT DISTINCT COUNT(DOC_TYPE) FROM DOCUMENTS вернёт число:
Anonymous Quiz
1%
Null
1%
0
7%
1
41%
2
5%
3
32%
4
13%
Выполнение запроса приведёт к SQL ошибке
👍11
В базе данных имеются, среди прочих, таблицы CLIENTS и CLIENTS_JUR_INFO, определённые следующим образом:
CREATE TABLE CLIENTS (
ID_CLIENT NUMBER NOT NULL PRIMARY KEY,
NAME_CLIENT VARCHAR(100) NOT NULL,
PHONE VARCHAR(30) DEFAULT NULL,
EMAIL VARCHAR(30) DEFAULT NULL,
IS_JUR NUMBER(2) DEFAULT 0 NOT NULL);
CREATE TABLE CLIENTS_JUR_INFO (
ID_CLIENT NUMBER NOT NULL PRIMARY KEY,
INN VARCHAR(20) DEFAULT NULL,
KPP VARCHAR(20) DEFAULT NULL,
CONSTRAINT FK1 FOREIGN KEY (ID_CLIENT) REFERENCES CLIENTS (ID_CLIENT));
CREATE TABLE CLIENTS (
ID_CLIENT NUMBER NOT NULL PRIMARY KEY,
NAME_CLIENT VARCHAR(100) NOT NULL,
PHONE VARCHAR(30) DEFAULT NULL,
EMAIL VARCHAR(30) DEFAULT NULL,
IS_JUR NUMBER(2) DEFAULT 0 NOT NULL);
CREATE TABLE CLIENTS_JUR_INFO (
ID_CLIENT NUMBER NOT NULL PRIMARY KEY,
INN VARCHAR(20) DEFAULT NULL,
KPP VARCHAR(20) DEFAULT NULL,
CONSTRAINT FK1 FOREIGN KEY (ID_CLIENT) REFERENCES CLIENTS (ID_CLIENT));
Между таблицами CLIENTS и CLIENTS_JUR_INFO:
Anonymous Quiz
57%
связь один-к-одному
33%
связь один-ко-многим
5%
связь многие-ко-многим
5%
нет связи
Всем доброго понедельника!
Лёгкая задачка по SQL. Ставлю одну звезду уровня сложности из пяти.
Лёгкая задачка по SQL. Ставлю одну звезду уровня сложности из пяти.
🔥7
В столбце COLOR таблицы GOODS указан цвет товара. У многих товаров может быть один и тот же цвет. Какой из запросов ниже вернёт количество возможных цветов товаров (один и тот же цвет не нужно учитывать более одного раза)?
Anonymous Quiz
5%
SELECT COUNT(t.COLOR) FROM GOODS t
1%
SELECT SUM(t.COLOR) FROM GOODS t
30%
SELECT DISTINCT COUNT(t.COLOR) FROM GOODS t
3%
SELECT DISTINCT SUM(t.COLOR) FROM GOODS t
59%
SELECT COUNT(DISTINCT t.COLOR) FROM GOODS t
3%
SELECT SUM(DISTINCT t.COLOR) FROM GOODS t
Всем привет!
Предлагаю решить ещё одну задачу по SQL🙂💪
В таблице SALES_TOTAL хранятся итоги по продажам каждого товара за каждый день. Запрос
SELECT t.*
FROM SALES_TOTAL t
WHERE t.PRODUCT_ID = 8
AND t.SALE_DATE >= '2024-01-01'
ORDER BY t.SALE_DATE
возвращает данные по продажам некоторого товара с идентификатором 8 за каждый день, начиная с начала 2024 года:
PRODUCT_ID SALE_DATE AMOUNT
8 2024-01-01 5
8 2024-01-02 4
8 2024-01-03 7
8 2024-01-04 8
...
В столбце AMOUNT отображается количество штук проданного товара за каждый день.
Предлагаю решить ещё одну задачу по SQL🙂💪
В таблице SALES_TOTAL хранятся итоги по продажам каждого товара за каждый день. Запрос
SELECT t.*
FROM SALES_TOTAL t
WHERE t.PRODUCT_ID = 8
AND t.SALE_DATE >= '2024-01-01'
ORDER BY t.SALE_DATE
возвращает данные по продажам некоторого товара с идентификатором 8 за каждый день, начиная с начала 2024 года:
PRODUCT_ID SALE_DATE AMOUNT
8 2024-01-01 5
8 2024-01-02 4
8 2024-01-03 7
8 2024-01-04 8
...
В столбце AMOUNT отображается количество штук проданного товара за каждый день.
Чтобы в результирующей таблице, помимо существующих столбцов, получить ещё один столбец с количеством проданного товара с начала года по день, указанный в таблице накопительным итогом, нужно в блок SELECT через запятую добавить:
Anonymous Quiz
21%
COUNT(AMOUNT) OVER(PARTITION BY PRODUCT_ID ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
4%
COUNT(AMOUNT) OVER ()
24%
SUM(AMOUNT) OVER (PARTITION BY SALE_DATE)
41%
SUM(AMOUNT) OVER (ORDER BY SALE_DATE ROWS UNBOUNDED PRECEDING)
3%
LAST_VALUE(AMOUNT) OVER (PARTITION BY SALE_DATE)
2%
LAST_VALUE(AMOUNT) OVER (ORDER BY SALE_DATE)
4%
LAST_VALUE(AMOUNT) OVER (ORDER BY SALE_DATE ROWS UNBOUNDED FOLLOWING)
👍4🔥2👻1
При каком уровне изоляции при повторном чтении таблицы в рамках одной транзакции будут получены те же данные, даже если в промежутке между чтениями они были изменены другой транзакцией и эти изменения подтверждены командой COMMIT?
Anonymous Quiz
32%
REPEATABLE READ
18%
SERIALIZABLE
32%
READ COMMITTED
18%
READ UNCOMMITTED
👍1
Всем привет!
Небольшая задача по SQL на внимательность (и на базовые знания):
В таблице PERSONS четыре записи:
ID NAME
1 Иванов Иван Иванович
2 Петров Павел Сергеевич
3 Сидовова Наталья Ивановна
4 Некрасов Иван Ильич
Небольшая задача по SQL на внимательность (и на базовые знания):
В таблице PERSONS четыре записи:
ID NAME
1 Иванов Иван Иванович
2 Петров Павел Сергеевич
3 Сидовова Наталья Ивановна
4 Некрасов Иван Ильич
👍4
Какое количество строк вернёт запрос SELECT * FROM PERSONS WHERE NAME LIKE 'Иван'
Anonymous Quiz
55%
0
4%
1
16%
2
21%
3
2%
4
3%
5
👍9🥱5