Я использую Oracle SQL.
ID | Name
----------
1 A
1 B
1 C
2 D
2 E
3 F
Я хочу получить столбец идентификатора, только если в поле «Имя» нет буквы A. Итак, для этого примера я бы хотел, чтобы результаты были только: 2, 3.
Как я могу этого добиться?
Я пытался:
select distinct ID
from table
where Name <> 'A'
Но это явно не сработало... Я также пробовал использовать listagg, но смог найти, как использовать в нем условие.
Используйте подзапрос с NOT IN
лайком,
select distinct ID
from table
where ID NOT IN (SELECT ID FROM table WHERE Name = 'A')
Вы можете использовать этот запрос
SELECT DISTINCT ID
FROM your_table t
WHERE NOT EXISTS (
SELECT 1
FROM your_table t_sub
WHERE t_sub.ID = t.ID
AND t_sub.Name = 'A'
);
И я также создаю этот пример: https://dbfiddle.uk/nlzwmeRn
Объедините строки с помощью GROUP BY id
. Затем используйте предложение HAVING
, чтобы сохранять только идентификаторы, у которых нет строки «A»:
select id
from table
group by id
having count(case when name = 'A' then 1 end) = 0;
Еще один простой вариант: получить все идентификаторы за вычетом идентификаторов «A»:
select id from table
minus
select id from table where name = 'A';
Ну, есть много способов подойти к этому :-)
В хорошо построенной базе данных типичное значение повторяющегося столбца имеет родительскую таблицу (во избежание опечаток). В вашем примере это может быть что-то вроде:
CREATE TABLE groups
(
group_id INT,
some_description_maybe VARCHAR(100),
PRIMARY KEY (group_id)
);
CREATE TABLE group_letters
(
group_id INT,
letter INT,
PRIMARY KEY (group_id, letter),
FOREIGN KEY (group_id) REFERENCING groups (group_id)
);
И типичный запрос будет использовать предложение NOT IN
или NOT EXISTS
. Помните: SELECT DISTINCT
очень часто является индикатором неподходящего запроса или неподходящей базы данных.
select *
from groups
where group_id not in (select group_id from group_letters where letter = 'A');
Спасибо, что приняли этот ответ. Однако я добавил комментарий о правильно построенной базе данных и ее типичном решении. Надеюсь, вы найдете это полезным.
выбрать отдельный идентификатор из таблицы минус выбрать идентификатор из таблицы, где имя = 'A'; будет лучше
@tahzibi.jafar: Почему? DISTINCT
было бы излишним, потому что MINUS
(и EXCEPT
в стандартном SQL) по умолчанию является отдельной операцией.
Из-за производительности (в минутах номинала). Если у нас меньше записей, МИНУС занимает меньше времени. Я знаю, что это добавляет некоторые накладные расходы при первом SELECT. в целом в больших наборах данных я думаю, что это лучше
@tahzibi.jafar: Вы неправильно понимаете, как работает SQL. Мы говорим СУБД, что делать, а не как это делать. При любом запросе СУБД может сначала удалить дубликаты, а затем применить MINUS
, или наоборот. Не пытайтесь каким-либо образом навязать СУБД. Пусть это решит. Не ставьте лишние DISTINCT
в своих запросах. Это скорее помешает СУБД найти оптимальный план выполнения, чем найти его (кстати, то же самое относится и к предложениям IN
.)
Теоретически ваш аргумент верен (и мы этого желаем). Но предложение основано на некоторых моих опытах (например, подсказках SQL).
Вы можете использовать предложение GROUP BY
с HAVING
, чтобы исключить те идентификаторы, у которых есть строки с именем = 'A':
SELECT id
FROM yourtable
GROUP BY id
HAVING COUNT(CASE WHEN name = 'A' THEN 1 END) = 0
ORDER BY id; --skip the ORDER BY clause if sorting is not intended
Посмотрите этот образец скрипта с вашими данными
Вы можете использовать запрос ниже. Просто замените имя таблицы
select ID
from LOCALWORK
where Name <> 'A' and
ID <>(Select ID from LOCALWORK where NAME='A')
group by ID
Нет. Если в таблице имеется более одной строки «А», вы получите ORA-01427: Подзапрос возвращает более одной строки. Вместо этого вы можете использовать <> ALL
, что довольно редко, или NOT IN
, как уже предлагалось. Также редко используется GROUP BY
без какой-либо функции агрегирования. В этом случае мы бы предпочли использовать DISTINCT
, чтобы прояснить наше намерение.
Понял! Спасибо. В подзапросе мы можем использовать различные, чтобы избавиться от ORA-01427.
Нет, мы не можем. Если в подзапросе есть два разных идентификатора, после DISTINCT
все равно будут два разных идентификатора.
Существующий ответ Рохана достигает цели SQL в этом ответе.
Вы можете использовать этот запрос для своего вопроса.
SELECT DISTINCT id FROM table_name
GROUP BY id
HAVING SUM(CASE WHEN name LIKE 'A' THEN 1 else 0 end) < 1
СУММА в части HAVING будет равна 0, если идентификатор содержит букву «А» в своем имени.
На будущее: 1. Всегда помечайте свои SQL-запросы своей СУБД, поскольку диалекты SQL различаются. 2. Никогда не говорите просто «это не сработало». Всегда сообщайте нам, почему это не сработало (сообщение об ошибке, слишком много строк, слишком мало строк, неправильные строки и т. д.) 3. Не вызывайте идентификатор столбца, если он не является идентификатором таблицы, который однозначно идентифицирует строку. . Хотя в вашем примере очевидно, что идентификатор — это не идентификатор, но при более сложных данных и задачах это может сильно запутать.