SELECT в Oracle SQL — 100 простых примеров для старта

🟢 SELECT в Oracle SQL. Введение

SELECT — основной оператор выборки в Oracle SQL. Он строит результирующие наборы из таблиц и представлений, поддерживает фильтрацию, сортировку, группировку, подзапросы, соединения, аналитические функции и многое другое.

Где используют

  • Отчёты и витрины: агрегации, сортировки, ограничение объёма выдачи.
  • Аналитика: оконные функции, ранжирование, скользящие расчёты.
  • Иерархии и графы: запросы с CONNECT BY и рекурсивный WITH.
  • Интеграции: подзапросы, JSON/XML‑извлечение, PIVOT/UNPIVOT.

Синтаксис SELECT

-- Базовый шаблон
SELECT [DISTINCT] expr_list
FROM   source
[WHERE condition]
[GROUP BY expr_list]
[HAVING condition]
[ORDER BY sort_list]
[OFFSET n ROWS] [FETCH {FIRST|NEXT} m ROWS {ONLY|WITH TIES}];

-- Примеры подзапросов и соединений
SELECT a.col, b.col
FROM   a
JOIN   b ON b.a_id = a.id;

100 простых примеров SELECT

1. Все колонки из таблицы

SELECT *
FROM employees;

2. Только нужные поля

SELECT emp_id, emp_name, hire_date
FROM employees;

3. Псевдонимы для удобного вывода

SELECT emp_name AS name, salary AS sal
FROM employees;

4. Арифметика и округление

SELECT emp_id, salary, ROUND(salary * 1.2, 2) AS salary_with_bonus
FROM employees;

5. DISTINCT для уникальных значений

SELECT DISTINCT dept_id
FROM employees;

6. Фильтрация по условию

SELECT emp_id, emp_name
FROM employees
WHERE dept_id = 10 AND salary > 5000;

7. Диапазон через BETWEEN

SELECT emp_id, salary
FROM employees
WHERE salary BETWEEN 3000 AND 7000;

8. Список значений через IN

SELECT emp_id, dept_id
FROM employees
WHERE dept_id IN (10,20,30);

9. Поиск по шаблону (LIKE)

SELECT emp_id, emp_name
FROM employees
WHERE emp_name LIKE 'A%';

10. Проверка на NULL

SELECT emp_id, manager_id
FROM employees
WHERE manager_id IS NULL;

11. Сортировка по одному полю

SELECT emp_id, emp_name, salary
FROM employees
ORDER BY salary DESC;

12. Сортировка по нескольким полям

SELECT emp_id, emp_name, dept_id, salary
FROM employees
ORDER BY dept_id, salary DESC;

13. Ограничение выдачи (FETCH FIRST)

SELECT emp_id, salary
FROM employees
ORDER BY salary DESC
FETCH FIRST 10 ROWS ONLY;

14. Пагинация через OFFSET/FETCH

SELECT emp_id, emp_name
FROM employees
ORDER BY emp_id
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

15. Агрегация по отделам

SELECT dept_id, AVG(salary) AS avg_sal, COUNT(*) AS cnt
FROM employees
GROUP BY dept_id;

16. Фильтр агрегатов (HAVING)

SELECT dept_id, AVG(salary) AS avg_sal
FROM employees
GROUP BY dept_id
HAVING AVG(salary) > 6000;

17. Производное поле через CASE

SELECT emp_name,
       CASE WHEN salary >= 6000 THEN 'HIGH' ELSE 'NORMAL' END AS band
FROM employees;

18. Подзапрос в IN

SELECT emp_id, emp_name
FROM employees
WHERE dept_id IN (SELECT dept_id FROM departments WHERE region = 'EU');

19. EXISTS с корреляцией

SELECT d.dept_id, d.dept_name
FROM departments d
WHERE EXISTS (
  SELECT 1 FROM employees e
  WHERE e.dept_id = d.dept_id
    AND e.salary > 8000
);

20. Скалярный подзапрос в списке вывода

SELECT emp_id, (SELECT dept_name FROM departments d WHERE d.dept_id = e.dept_id) AS dept_name
FROM employees e;

Еще 20 примеров.

21. Перекрёстное соединение

SELECT a.*, b.*
FROM a
CROSS JOIN b;

22. Внутреннее соединение по ключу

SELECT e.emp_name, d.dept_name
FROM employees e
JOIN departments d ON d.dept_id = e.dept_id;

23. Левое внешнее соединение

SELECT e.emp_name, d.dept_name
FROM employees e
LEFT JOIN departments d ON d.dept_id = e.dept_id;

24. Правое внешнее соединение

SELECT e.emp_name, d.dept_name
FROM employees e
RIGHT JOIN departments d ON d.dept_id = e.dept_id;

25. Полное внешнее соединение

SELECT e.emp_name, d.dept_name
FROM employees e
FULL OUTER JOIN departments d ON d.dept_id = e.dept_id;

26. Иерархический обход (корни)

SELECT emp_id, emp_name, LEVEL
FROM employees
START WITH manager_id IS NULL
CONNECT BY PRIOR emp_id = manager_id;

27. Стабильная сортировка ветвей

SELECT emp_id, emp_name, LEVEL
FROM employees
START WITH manager_id IS NULL
CONNECT BY PRIOR emp_id = manager_id
ORDER SIBLINGS BY emp_name;

28. Путь до узла

SELECT emp_id, SYS_CONNECT_BY_PATH(emp_name,' / ') AS path
FROM employees
START WITH manager_id IS NULL
CONNECT BY PRIOR emp_id = manager_id;

29. ROW_NUMBER для ранжирования

SELECT emp_id, salary,
       ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rn
FROM employees;

30. RANK и DENSE_RANK

SELECT emp_id, salary,
       RANK() OVER (ORDER BY salary DESC) AS rnk,
       DENSE_RANK() OVER (ORDER BY salary DESC) AS drnk
FROM employees;

31. Оконная сумма по отделу

SELECT emp_id, dept_id, salary,
       SUM(salary) OVER (PARTITION BY dept_id ORDER BY emp_id) AS run_sum
FROM employees;

32. LAG/LEAD для сравнения соседей

SELECT emp_id, salary,
       LAG(salary)  OVER (ORDER BY emp_id) AS prev_sal,
       LEAD(salary) OVER (ORDER BY emp_id) AS next_sal
FROM employees;

33. LISTAGG в одну строку

SELECT dept_id,
       LISTAGG(emp_name, ', ') WITHIN GROUP (ORDER BY emp_name) AS employees_list
FROM employees
GROUP BY dept_id;

34. PIVOT — годы по колонкам

SELECT *
FROM sales
PIVOT ( SUM(amount) FOR year IN (2023, 2024, 2025) );

35. UNPIVOT — разворот по атрибутам

SELECT product_id, metric, val
FROM sales_metrics
UNPIVOT ( val FOR metric IN (q1, q2, q3, q4) );

36. CTE через WITH

WITH recent AS (
  SELECT * FROM orders WHERE order_date >= DATE '2025-01-01'
)
SELECT order_id, customer_id FROM recent;

37. Рекурсивный WITH (дерево отделов)

WITH dept_tree (dept_id, parent_id, lvl) AS (
  SELECT dept_id, parent_id, 1 FROM departments WHERE parent_id IS NULL
  UNION ALL
  SELECT d.dept_id, d.parent_id, t.lvl+1
  FROM departments d JOIN dept_tree t ON d.parent_id = t.dept_id
)
SELECT * FROM dept_tree;

38. JSON_VALUE в колонках

SELECT order_id,
       JSON_VALUE(jdoc, '$.customer.id') AS customer_id,
       JSON_VALUE(jdoc, '$.amount') AS amount
FROM orders_json;

39. JSON_TABLE для реляционного вида

SELECT jt.id, jt.qty
FROM orders o,
     JSON_TABLE(o.jdoc, '$.lines[*]'
       COLUMNS ( id NUMBER PATH '$.id', qty NUMBER PATH '$.qty')) jt;

40. UNION для объединения наборов

SELECT id, name FROM a
UNION
SELECT id, name FROM b;

Еще 20 примеров.

41. UNION ALL без удаления дублей

SELECT id, name FROM a
UNION ALL
SELECT id, name FROM b;

42. INTERSECT — пересечение

SELECT id FROM a
INTERSECT
SELECT id FROM b;

43. MINUS — разность множеств

SELECT id FROM a
MINUS
SELECT id FROM b;

44. Функции строк: SUBSTR/INSTR

SELECT emp_name,
       SUBSTR(emp_name,1,3) AS prefix,
       INSTR(emp_name,' ')   AS space_pos
FROM employees;

45. Регулярные выражения в фильтре

SELECT email
FROM users
WHERE REGEXP_LIKE(email, '^[^@]+@example\.com$');

46. Извлечение компонент даты

SELECT hire_date,
       EXTRACT(YEAR FROM hire_date)  AS y,
       EXTRACT(MONTH FROM hire_date) AS m
FROM employees;

47. Форматирование даты в строку

SELECT TO_CHAR(order_date, 'YYYY-MM-DD') AS d
FROM orders;

48. Арифметика дат (плюс 7 дней)

SELECT order_id, order_date, order_date + 7 AS eta
FROM orders;

49. Числовое форматирование

SELECT amount, TO_CHAR(amount,'FM999G999D00') AS formatted
FROM payments;

50. DECODE для кодов

SELECT code, DECODE(code,'A','Alpha','B','Beta','Other') AS label
FROM dict;

51. Коррелированный подзапрос с агрегатом

SELECT e.emp_id, e.salary,
       (SELECT AVG(salary) FROM employees x WHERE x.dept_id = e.dept_id) AS dept_avg
FROM employees e;

52. EXISTS для проверки наличия

SELECT d.dept_id, d.dept_name
FROM departments d
WHERE EXISTS (SELECT 1 FROM employees e WHERE e.dept_id = d.dept_id);

53. SAMPLE — случайная доля строк

SELECT *
FROM big_table SAMPLE (5);

54. FOR UPDATE блокировка строк

SELECT *
FROM orders
WHERE status = 'NEW'
FOR UPDATE;

55. FOR UPDATE SKIP LOCKED для очередей

SELECT *
FROM tasks
WHERE status = 'NEW'
FOR UPDATE SKIP LOCKED;

56. NOWAIT при блокировке

SELECT *
FROM tasks
WHERE status = 'NEW'
FOR UPDATE NOWAIT;

57. Подставной столбец с константой

SELECT emp_id, 'ACTIVE' AS status
FROM employees;

58. Ограничение столбцов через выражение

SELECT emp_id, salary * 12 AS salary_year
FROM employees;

59. Скалярная функция в списке вывода

SELECT emp_id, UPPER(emp_name) AS up_name
FROM employees;

60. Агрегаты без группировки (итоги)

SELECT COUNT(*) AS cnt, MIN(salary) AS min_sal, MAX(salary) AS max_sal
FROM employees;

Еще 20 примеров.

61. HAVING с COUNT(*)

SELECT dept_id
FROM employees
GROUP BY dept_id
HAVING COUNT(*) >= 5;

62. ORDER BY по выражению

SELECT emp_id, salary * 12 AS y
FROM employees
ORDER BY y DESC;

63. FETCH WITH TIES для «ничего не потерять»

SELECT emp_id, salary
FROM employees
ORDER BY salary DESC
FETCH FIRST 3 ROWS WITH TIES;

64. Подзапрос в FROM (inline view)

SELECT t.dept_id, t.cnt
FROM (
  SELECT dept_id, COUNT(*) AS cnt
  FROM employees
  GROUP BY dept_id
) t;

65. USING в соединении по одноимённым

SELECT *
FROM a JOIN b USING (id);

66. Сортировка с NULLS LAST

SELECT salary
FROM employees
ORDER BY salary NULLS LAST;

67. Ограничение по ROWNUM (устаревший паттерн)

SELECT *
FROM (
  SELECT * FROM employees ORDER BY salary DESC
)
WHERE ROWNUM <= 10;

68. DISTINCT вместе с агрегатами

SELECT COUNT(DISTINCT dept_id) AS dept_cnt
FROM employees;

69. Оконное среднее «скользящее»

SELECT ts, val,
       AVG(val) OVER (ORDER BY ts ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS mov_avg
FROM metrics;

70. GROUPING SETS для нескольких срезов

SELECT dept_id, job, SUM(salary) AS s
FROM employees
GROUP BY GROUPING SETS ((dept_id, job), (dept_id), ());

71. ROLLUP для иерархических итогов

SELECT dept_id, job, SUM(salary) AS s
FROM employees
GROUP BY ROLLUP (dept_id, job);

72. CUBE для всех комбинаций

SELECT region, dept_id, SUM(salary) AS s
FROM employees
GROUP BY CUBE (region, dept_id);

73. MINUS с ORDER BY во внешней оболочке

SELECT * FROM (
  SELECT id FROM a
  MINUS
  SELECT id FROM b
) t
ORDER BY id;

74. INTERSECT с FETCH FIRST

SELECT * FROM (
  SELECT id FROM a
  INTERSECT
  SELECT id FROM b
)
FETCH FIRST 5 ROWS ONLY;

75. Псевдотаблица DUAL

SELECT 'hello' AS greeting
FROM dual;

76. CASE в ORDER BY для кастомной сортировки

SELECT status, created_at
FROM orders
ORDER BY CASE status WHEN 'NEW' THEN 1 WHEN 'PENDING' THEN 2 ELSE 3 END, created_at;

77. Все колонки из таблицы

SELECT *
FROM employees;

78. Только нужные поля

SELECT emp_id, emp_name, hire_date
FROM employees;

79. Псевдонимы для удобного вывода

SELECT emp_name AS name, salary AS sal
FROM employees;

80. Арифметика и округление

SELECT emp_id, salary, ROUND(salary * 1.2, 2) AS salary_with_bonus
FROM employees;

Еще 20 примеров.

81. DISTINCT для уникальных значений

SELECT DISTINCT dept_id
FROM employees;

82. Фильтрация по условию

SELECT emp_id, emp_name
FROM employees
WHERE dept_id = 10 AND salary > 5000;

83. Диапазон через BETWEEN

SELECT emp_id, salary
FROM employees
WHERE salary BETWEEN 3000 AND 7000;

84. Список значений через IN

SELECT emp_id, dept_id
FROM employees
WHERE dept_id IN (10,20,30);

85. Поиск по шаблону (LIKE)

SELECT emp_id, emp_name
FROM employees
WHERE emp_name LIKE 'A%';

86. Проверка на NULL

SELECT emp_id, manager_id
FROM employees
WHERE manager_id IS NULL;

87. Сортировка по одному полю

SELECT emp_id, emp_name, salary
FROM employees
ORDER BY salary DESC;

88. Сортировка по нескольким полям

SELECT emp_id, emp_name, dept_id, salary
FROM employees
ORDER BY dept_id, salary DESC;

89. Ограничение выдачи (FETCH FIRST)

SELECT emp_id, salary
FROM employees
ORDER BY salary DESC
FETCH FIRST 10 ROWS ONLY;

90. Пагинация через OFFSET/FETCH

SELECT emp_id, emp_name
FROM employees
ORDER BY emp_id
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

91. Агрегация по отделам

SELECT dept_id, AVG(salary) AS avg_sal, COUNT(*) AS cnt
FROM employees
GROUP BY dept_id;

92. Фильтр агрегатов (HAVING)

SELECT dept_id, AVG(salary) AS avg_sal
FROM employees
GROUP BY dept_id
HAVING AVG(salary) > 6000;

93. Производное поле через CASE

SELECT emp_name,
       CASE WHEN salary >= 6000 THEN 'HIGH' ELSE 'NORMAL' END AS band
FROM employees;

94. Подзапрос в IN

SELECT emp_id, emp_name
FROM employees
WHERE dept_id IN (SELECT dept_id FROM departments WHERE region = 'EU');

95. EXISTS с корреляцией

SELECT d.dept_id, d.dept_name
FROM departments d
WHERE EXISTS (
  SELECT 1 FROM employees e
  WHERE e.dept_id = d.dept_id
    AND e.salary > 8000
);

96. Скалярный подзапрос в списке вывода

SELECT emp_id, (SELECT dept_name FROM departments d WHERE d.dept_id = e.dept_id) AS dept_name
FROM employees e;

97. Перекрёстное соединение

SELECT a.*, b.*
FROM a
CROSS JOIN b;

98. Внутреннее соединение по ключу

SELECT e.emp_name, d.dept_name
FROM employees e
JOIN departments d ON d.dept_id = e.dept_id;

99. Левое внешнее соединение

SELECT e.emp_name, d.dept_name
FROM employees e
LEFT JOIN departments d ON d.dept_id = e.dept_id;

100. Правое внешнее соединение

SELECT e.emp_name, d.dept_name
FROM employees e
RIGHT JOIN departments d ON d.dept_id = e.dept_id;

Частые ошибки и подводные камни

  1. Неявные преобразования. Разные типы в сравнениях приводят к неожиданным планам; приводите явно.
  2. Фильтры и индексы. Функции над колонками в WHERE могут «ломать» индекс; используйте функциональные индексы.
  3. Группировка. Всё, что не агрегат — должно быть в GROUP BY.
  4. Ограничение выдачи. Для стабильной пагинации используйте детерминированный ORDER BY вместе с OFFSET/FETCH.

Альтернативы

  • JSON_TABLE/XMLTABLE — когда источник — документы.
  • MODEL — расчёты в табличной форме (продвинутые сценарии).
  • Рекурсивный WITH — альтернатива иерархическим запросам для произвольных правил обхода.

Заключение

SELECT — сердце SQL. Стройте только необходимые колонки, пишите селективные условия, фиксируйте порядок и используйте оконные функции там, где это упрощает логику.

Документация

Queries and Subqueries

SELECT — полное описание


🔜 Следующая статья:

ZONE в Oracle SQL — как использовать часовые пояса


Понравилась статья? Поделиться с друзьями: