2016-11-07 8 views
3

я борюсь с запросом SQL, она должна быть основана на структуре таблицы, как это:ВЫБРАТЬ синтаксис Oracle для получения dupicate записей с помощью EXISTS и директив

PID (type VARCHAR) ATTR (type VARCHAR) 
U1     attribute1 
U1     locale 
U2     attribute1 
U2     locale 
U3     attribute1 
U3     attribute2 

То, что я хотел бы сделать, это выбрать все PID S не имеющих запись, содержащую строку «языковой» в столбце атр, поэтому в данном примере я показал, этот запрос должен возвращать «U3»

Я попытался запросы, как:

SELECT DISTINCT PID p 
FROM tablename 
WHERE NOT EXISTS (SELECT * FROM table 
        WHERE PID = 'p' AND ATTR NOT IN 'locale'); 

и тому подобное, но я либо не правильно понял синтаксис SQL, либо делал некоторые другие ошибки - я не получаю правильных результатов.

Есть ли у кого-нибудь идеи, что может пойти не так?

P.S. Ребята, должная обратная связь, я получил, я должен сделать что-то неправильно, позвольте мне, пожалуйста, заполнить некоторую информацию, может быть, это поможет.

Таблица, в которой я говорю, представляет собой стандартную таблицу стека SAP J2EE (UME_STRINGS), содержащую пользовательские данные (UME в терминах SAP - механизм управления пользователями). Он содержит много других полей рядом с PID и ATTR, я не рассматривал их, так как кажется, что они не имеют значения.

Однако мне нужно найти все учетные записи пользователей без установленного языкового стандарта. Так как пользовательское управление работает «ленивым», очевидно, такая запись (запись с произвольным PID и значением «locale» в ATTR) будет создана только после установки локали. Это означает, что на самом деле в таблице имеется много произвольных записей (такое же значение PID), но ни одно из них не имеет значения «locale» в поле ATTR. Таким образом, алго может быть:

1.) группироваться таблицей на идентичном PID-

2.) итерация по скоплению и проверить внутри каждый кластер, если нет записи с «локал» в поле атра в этот кластер, добавить PID к выходу

3.) вернуть список найденного PID-

Всем это будет сделано в идеале с помощью одного запроса SQL.

Доступный JAVA API (com.sap.security.api.IUserSearchFilter) не позволяет устанавливать нулевые значения для поиска, поэтому у меня нет выбора, кроме как напрямую обращаться к БД.

Кроме записей «локали», конечно, многие другие, потому что каждый атрибут для пользователя, группы, роли и т.д. моделируется таким образом - такие вещи, как U1 - attribute1 и т.д.

Так что мне нужно это запрос давая мне PID для пользователей, у которых нет записи, как «PID -„локаль“в ATTR

Если мое описание запутанной или неполной, пожалуйста, спросите Еще раз спасибо

ПФС..добавлены несколько скриншотов с данными выборки и структуры таблицы

table structure

sample data

could PID be null?

+0

Can PID be null? (Вы можете проверить свои фактические данные: 'select count (PID), где PID равен null'). – mathguy

+0

Нет, из-за ER всегда имеет значение –

ответ

4

Нет необходимости EXISTS() или IN(), вы можете просто использовать предложение HAVING с CASE EXPRESSION:

SELECT t.pid 
FROM YourTable t 
GROUP BY t.pid 
HAVING COUNT(CASE WHEN t.attr = 'locale' THEN 1 END) = 0 
+0

Спасибо, звучит правильно, но на самом деле поставляет слишком много данных, также U1 и U2. На самом деле должен появиться только U3. Может, я что-то сделал или забыл что-то сказать? –

+0

@JohnDoe - этот ответ правильный (и некоторые другие ответы были правильными тоже), поэтому вы должны делать что-то неправильно. Поделитесь некоторыми данными, в которых вы чувствуете, что этот запрос приводит к неправильному результату. – mathguy

+0

У меня такое же чувство математики, я представлял лишь экстракт проблемы, чтобы все было просто. Не кажется, что это была хорошая идея, я отредактировал весь свой пост и добавил некоторую информацию, может быть, это поможет –

0

Вы можете использовать не IN и субтропических выберите

SELECT DISTINCT PID 
FROM tablename 
WHERE PID NOT IN (SELECT PID FROM table 
         WHERE ATTR = 'locale'); 

TRIM(BOTH FROM ATTR) в конечном счете попробовать

SELECT DISTINCT PID 
FROM tablename 
WHERE PID NOT IN (SELECT PID FROM table 
         WHERE LOWER(TRIM(BOTH FROM ATTR))= 'locale'); 
+1

'NOT IN NOT'? .. – sagi

+0

спасибо, но неправильный синтаксис, вообще-то не работает. Im на 11g, может быть, это важно –

+0

Отвечено обновлено .. NOT IN – scaisEdge

0

Вы можете сделать это

SELECT DISTINCT PID 
FROM tableName 
WHERE PID NOT IN (SELECT PID FROM tableName WHERE Attr = 'locale') 
+0

Спасибо, но поставляет слишком много данных, аналогичных ответу саги. Я ожидаю, что станет только значением, которое не имеет записей с произвольным значением PID и «locale» в ATTR.В моем примере это будет U3 –

+0

выше запроса возвращает U3 только потому, что U2 и U1 имеют строки с значением Attr как locale –

+0

нет, если я запускаю запрос на своей машине (сервер Oracle 11g, Win 2008 R2), спасибо вам в любом случае. У меня такое ощущение, что мой сценарий не завершен, я добавил некоторую информацию на весь свой пост, пожалуйста, не стесняйтесь спрашивать, не пропали ли вы что-то. –

0
SELECT DISTINCT PID p 
FROM tablename t 
WHERE NOT EXISTS (SELECT * FROM tablename t2 
        WHERE t2.PID = t.PID AND t2.ATTR = 'locale'); 
+0

Спасибо, но поставляет «не выбранных строк» ​​ –

+0

, которые должны были быть «... ГДЕ НЕ EXISTS (SELECT * FROM tablename t2 WHERE t2.PID = t.PID AND t2.ATTR = 'locale'); ' – joop

+0

спасибо, но похоже на другие ответы, он предоставляет слишком много данных - очевидно, также такие записи, как U1 - attribute1, мы не хотим делать это –

0

Попробуйте это. Проблема n некоторых других запросов заключается в том, что не существует, выглядит только для локализации attr, с помощью wID с помощью PID.

select t1.pid from tablename t1 
where not exists 
(select t2.pid from tablename t2 where t2.pid=t1.pid and t2.attr='locale');