#mysql
Вопрос:
Я хочу выбрать всех сотрудников, если ни один сотрудник не выбран, иначе нужны данные для выбранного сотрудника.
Я написал этот запрос, но он выдает ошибку.
DECLARE @emp_id INT
SET @emp_id=0 -- This will change based on the selected employee from UI
SELECT * FROM employees
WHERE employee_id in (CASE WHEN @emp_id=0 THEN (SELECT employee_id FROM employees) ELSE @emp_id END)
Пример сценария для воспроизведения проблемы
CREATE TABLE employees (
employee_id INT ,
first_name VARCHAR (20) DEFAULT NULL,
last_name VARCHAR (25) NOT NULL
);
INSERT INTO employees values (1, '1_fname', '1_lname'),(2, '2_fname', '2_lname'),(3, '3_fname', '3_lname'),(4, '4_fname', '4_lname'),(5, '5_fname', '5_lname')
Я хочу сделать это одним запросом.
Комментарии:
1. Это в хранимой процедуре? Если да, то, вероятно, вы можете использовать оператор CASE , а не оператор CASE
2. нет , это не в хранимой процедуре. Это будет встроенный запрос. Для простоты я поместил здесь вот так.
3. при необходимости я могу создать хранимую процедуру. Но я получаю ошибку в этом запросе в workbench. как устранить ошибку.
Ответ №1:
Предполагая, что вы используете подготовленные заявления, вам нужно будет указать выбранного сотрудника 2 раза — в качестве аргументов 1 и 2:
SELECT * FROM employees
WHERE CASE WHEN COALESCE(?,0) = 0 THEN TRUE ELSE id = ? END
Комментарии:
1. как это вернет всех сотрудников в случае, если ни один сотрудник не будет выбран ? Предположим, что я хочу добавить какое-то предложение where в подзапросе или выбрать идентификатор сотрудника из другой таблицы.
2. Просто — если вы предоставите ненулевой идентификатор сотрудника для подготовленного запроса, он вернет этого конкретного сотрудника. Если вы укажете 0 или NULL — запрос вернет все записи из таблицы
employees
, без определенного порядка.3. но я могу изменить таблицу внутреннего запроса с помощью предложения where. Мне нужен идентификатор сотрудника во внутреннем запросе из разных таблиц в зависимости от условий. Из внутреннего запроса я имею в виду запрос в операторе case в моем примере.
4. Это условие должно быть определено вне SQL — например, в PHP, Node, C# или любом другом серверном языке, который вы используете. Как только условие будет определено — вы выдадите этот предопределенный SQL — запрос, соответствующий фактическому условию. Например, если вам нужны все сотрудники — вы будете работать
SELECT * FROM employees
, но если вам нужен один сотрудник-вы будете работатьSELECT * FROM employees WHERE id IN (SELECT employee_id FROM some_other_table WHERE some_other_condition)
Ответ №2:
Для одного запроса мы можем INNER JOIN
с помощью одной и той же таблицы эмулировать, должны ли сотрудники отображаться или нет. Использование этого запроса приведет к желаемому результату.
select e.*
from employees e
inner join (
select employee_id,
case
when @emp_id = 0 then true -- will display all employees
when @emp_id = @emp_id then true -- only display selected employee
else false
end as is_shown
from employees
) filter on e.employee_id = filter.employee_id and filter.is_shown = 1;
Или использовать другой подход
select employee_id, first_name, last_name
from (
select e.*,
case
when @emp_id = 0 then true
when @emp_id = employee_id then true
else false
end as is_shown
from employees e
) employees
where is_shown = 1;
Простое управление потоком внутри хранимой процедуры
delimiter $
use `precise`$
drop procedure if exists `GetEmployee`$
create definer=`user`@`%` procedure `GetEmployee`(empID int)
begin
case when empID = 0 then
select *
from employees;
else
select *
from employees
where employee_id = empID;
end case
;
end$
delimiter ;
Комментарии:
1. Я хочу сделать это в одном запросе. Извините за путаницу. Я обновил свой вопрос.
2. Я обновил свой ответ, включив в него один запрос.