Вопросы 31-40 для разработчиков
Ответ: SELF JOIN — это join в котором таблица объединяется сама с собой. Это полезно когда строки в одной таблице имеют отношение, такие как сотрудники и их менеджеры или продукты и их родительские продукты. Используются отдельные alias таблицы для различия между двумя экземплярами одной таблицы.
SELECT e.EmployeeName,
m.EmployeeName AS Manager
FROM Employees e
LEFT JOIN Employees m ON e.ManagerID = m.EmployeeID;
-- Выход: каждый сотрудник с именем его менеджера
Ответ: Клауза GROUP BY используется для организации одинаковых данных в группы. Обычно используется с агрегатными функциями (COUNT, SUM, AVG) для выполнения вычислений на каждой группе, а не на всем наборе данных.
SELECT dept_id, COUNT(*) AS employee_count, AVG(salary) AS avg_salary
FROM employees
GROUP BY dept_id;
-- Возвращает количество сотрудников и среднюю зарплату по каждому отделу
SELECT dept_id, COUNT(*) AS emp_count
FROM employees
GROUP BY dept_id
HAVING COUNT(*) > 5;
-- Возвращает только отделы с более чем 5 сотрудниками
Ответ: Агрегатные функции выполняют вычисления на наборе значений и возвращают одно значение. Обычно используются с GROUP BY для выполнения расчетов на каждой группе.
SELECT COUNT(*) FROM employees;
SELECT SUM(salary) FROM employees;
SELECT AVG(salary) FROM employees;
SELECT MIN(salary) FROM employees;
SELECT MAX(salary) FROM employees;
Ответ: Индексы — это объекты БД, которые улучшают производительность запросов, позволяя быстрее получать строки. Работают как индекс в книге, позволяя быстро найти данные без сканирования всей таблицы. Однако индексы требуют дополнительную память и могут замедлить операции модификации данных.
-- Простой индекс
CREATE INDEX idx_emp_name ON employees(emp_name);
-- Составной индекс
CREATE INDEX idx_dept_salary ON employees(dept_id, salary);
-- Уникальный индекс
CREATE UNIQUE INDEX idx_email ON users(email);
-- Удаление индекса
DROP INDEX idx_emp_name;
| DELETE | TRUNCATE |
|---|---|
| Удаляет строки одну за одной, логирует каждое удаление | Удаляет все строки сразу, минимальное логирование, быстрее |
| Это DML команда | Это DDL команда |
| Поддерживает WHERE клаузу для выборочного удаления | Не поддерживает WHERE клаузу - удаляет ВСЕ строки |
| Медленнее из-за логирования | Намного быстрее |
| Поддерживает ROLLBACK | Не поддерживает ROLLBACK |
| Не сбрасывает identity | Сбрасывает identity (автоинкремент) на seed value |
DELETE - Удалить выборочно:
-- Удалить сотрудников с зарплатой < 30000
DELETE FROM employees WHERE salary < 30000;
-- Отменить (ROLLBACK)
ROLLBACK;
TRUNCATE - Удалить все:
-- Удалить все строки (очень быстро!)
TRUNCATE TABLE employees;
-- Отменить не получится (в автокоммит режиме)
| SQL Databases | NoSQL Databases |
|---|---|
| Используют структурированные таблицы с строками и столбцами | Используют гибкие структуры без схемы, такие как key-value или документы |
| Следуют фиксированной схеме | Не требуют фиксированной схемы |
| Поддерживают ACID свойства для надежных транзакций | Часто приоритизируют производительность и масштабируемость над строгой консистентностью |
| Лучше для структурированных и стабильных данных | Подходят для больших, быстро меняющихся и неструктурированных данных |
| Масштабируются вертикально (увеличение ресурсов) | Масштабируются горизонтально (добавление новых серверов) |
Ответ: Constraints — это правила, применяемые к столбцам таблицы для гарантирования целостности и качества данных.
CREATE TABLE employees (
emp_id INT NOT NULL,
emp_name VARCHAR(100) NOT NULL
);
CREATE TABLE users (
email VARCHAR(100) UNIQUE
);
CREATE TABLE products (
product_id INT PRIMARY KEY
);
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
CREATE TABLE employees (
salary DECIMAL(10,2) CHECK (salary > 0)
);
CREATE TABLE orders (
order_date DATE DEFAULT GETDATE(),
status VARCHAR(20) DEFAULT 'Pending'
);
Ответ: Cursor — это объект БД, используемый для получения, манипулирования и прохождения через строки в результирующем наборе одну строку за раз. Cursors полезны для операций, которые должны обрабатываться последовательно, а не в set-based манере.
DECLARE @emp_name VARCHAR(100);
DECLARE emp_cursor CURSOR FOR
SELECT emp_name FROM employees WHERE salary > 50000;
OPEN emp_cursor;
FETCH NEXT FROM emp_cursor INTO @emp_name;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @emp_name;
FETCH NEXT FROM emp_cursor INTO @emp_name;
END
CLOSE emp_cursor;
DEALLOCATE emp_cursor;
Ответ: Trigger — это набор SQL statements, которые автоматически выполняются в ответ на определенные события в таблице, такие как INSERT, UPDATE или DELETE. Triggers помогают поддерживать консистентность данных, обеспечивать бизнес-правила и реализовывать сложные constraints целостности.
-- AFTER INSERT Trigger - логирование при добавлении сотрудника
CREATE TRIGGER tr_log_employee_insert
AFTER INSERT ON employees
FOR EACH ROW
BEGIN
INSERT INTO employee_audit (emp_id, action, action_date)
VALUES (NEW.emp_id, 'INSERT', GETDATE());
END;
-- BEFORE UPDATE Trigger - проверка перед обновлением зарплаты
CREATE TRIGGER tr_validate_salary_update
BEFORE UPDATE ON employees
FOR EACH ROW
BEGIN
IF NEW.salary < 0 THEN
RAISE EXCEPTION 'Salary cannot be negative';
END IF;
END;
Ответ: SELECT statement используется для получения данных из одной или нескольких таблиц. Это наиболее часто используемая команда в SQL, позволяющая пользователям фильтровать, сортировать и отображать данные на основе определенных критериев.
SELECT [DISTINCT] column1, column2, ...
FROM table_name
[WHERE condition]
[GROUP BY column1, column2, ...]
[HAVING condition]
[ORDER BY column1 [ASC|DESC], ...]
[LIMIT/OFFSET rows];
-- Простой SELECT
SELECT emp_name, salary FROM employees;
-- SELECT с условиями
SELECT emp_name, salary
FROM employees
WHERE salary > 50000 AND dept_id = 10;
-- SELECT с GROUP BY
SELECT dept_id, COUNT(*) as emp_count, AVG(salary)
FROM employees
GROUP BY dept_id;
-- SELECT с JOIN
SELECT e.emp_name, d.dept_name
FROM employees e
INNER JOIN departments d ON e.dept_id = d.dept_id;
-- SELECT с ORDER BY и LIMIT
SELECT * FROM employees
ORDER BY salary DESC
LIMIT 10;