У меня есть таблица с несколькими столбцами (SQL Server). Однако только два столбца имеют отношение к вопросу.
Столбец a = ID (числовое значение)
Столбец b = Статус (строка)
Я хочу вернуть только те строки, которые содержат одно значение «Apple», в данном случае это будет строка 3, идентификатор 101.
Хотя другие идентификаторы также имеют значение «Apple», они меня не интересуют, поскольку у них есть и другие значения.
Я пробовал комбинации IF, HAVING, с выражениями Case и разделами. Я думал, что у меня это было пару раз, но, к сожалению, нет.
Вот одна из моих неправильных попыток:
SELECT
ID
, STATUS
FROM table name
GROUP BY ID, STATUS
HAVING COUNT(DISTINCT STATUS) = 1
AND MAX(STATUS) = 'APPLE'
И это:
SELECT
ID
, STATUS
, IF(SUM(CASE WHEN STATUS = 'Apple' THEN 1 ELSE 0 END)
OVER (PARTITION BY id) >0, 'TRUE', 'FALSE') AS Q_IDENTIFIER
FROM table_name
Моя ошибка, сейчас исправлю, сб 101
Может ли кто-нибудь иметь несколько яблок?
Теоретически у кого-то может быть несколько Apple, поэтому, если мы добавим идентификатор 103, он может иметь две строки, обе из которых будут читать Apple.
И вы бы хотели, чтобы они были включены? Исключено? Вы ожидаете 1 ряд или 2+?


Есть несколько способов очистить это яблоко.
CREATE TABLE #Data (ID INT, Status NVARCHAR(100))
INSERT INTO #Data
SELECT *
FROM
(
VALUES (100, N'Banana')
, (100, N'Apple')
, (101, N'Apple')
, (102, N'Banana')
, (102, N'Apple')
, (102, N'Grape')
) t (ID,Status)
Оконные агрегаты:
SELECT *
FROM (
SELECT *
, COUNT(*) OVER(partition BY ID) AS totalCount
FROM #Data
) x
WHERE Status = 'Apple'
AND totalCount = 1
При этом заранее подсчитываются все строки для каждого идентификатора, что позволяет затем отфильтровать нужные строки за пределами подзапроса.
Существует:
SELECT *
FROM #Data d
WHERE Status = 'Apple'
AND NOT EXISTS(
SELECT 1
FROM #Data d2
WHERE d2.ID = d.ID
AND d2.Status <> d.Status
)
Это просто проверяет, нет ли других строк в той же ID-группе. Возврат дубликатов может иметь недостатки, если у вас доступно более одного Apple.
По коррелированной логике
select * from tdata t1 where 1 =
( select count(id) from tdata t2
where t2.id = t1.id and t1.status='Apple');
«Я пробовал комбинации IF, HAVING с операторами Case и разделами». Вы забыли продемонстрировать эти попытки; это звучит именно то, что вам следует использовать.