Извлеките всех сотрудников, если не выбран сотрудник из пользовательского интерфейса, или выберите конкретные данные о сотрудниках

#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. Я обновил свой ответ, включив в него один запрос.