Запрос SQL для поиска False Negatives по согласованию данных или разрешению сущности

75
9

Предположим, у меня есть два разных идентификатора, назначенных для одной записи. Например


RecordID | ID1 | ID2
--------------------
1 | X | A
2 | X | B
3 | Y | C
4 | Y | C
5 | Y | D
6 | Z | E
7 | Z | E

Теперь я хочу получить записи, где ID1 присваивается тому же значению, где ID2 присваивается другому значению.

Например, я хочу получить:

1, X, A
2, X, B

Здесь ID1 назначил ему X, где, когда ID2 назначил ему A и B, два разных значения.

Можно ли написать запрос на SQL или SQL-сервере, который вернет такие записи?

спросил(а) 2013-02-07T00:27:00+04:00 8 лет назад
1
Решение
61

Вам нужно использовать подзапрос, в котором для каждой строки вы пробиваете таблицу и видите, соответствуют ли какие-либо другие строки определенным критериям, связанным с ней.

псевдо sql:

select 
t1.id,
t1.variable,
t1.value
from
table t1
where
exists ( select 1
from t2
where t2.id != t1.id
and t2.variable == t1.variable
and t2.value != t1.value)

ответил(а) 2013-02-07T00:33:00+04:00 8 лет назад
60

Если это SQL Server 2005+:

WITH minmax AS (
SELECT
*,
minID2 = MIN(ID2) OVER (PARTITION BY ID1),
maxID2 = MAX(ID2) OVER (PARTITION BY ID1)
FROM atable
)
SELECT
RecordID,
ID1,
ID2
FROM minmax
WHERE minID2 <> maxID2
;

В minmax CTE minmax два столбца, которые содержат минимальный и максимальный ID2 для каждой группы строк с тем же ID1. Основной запрос возвращает только те строки, где соответствующий минимальный ID2 не соответствует максимальному ID2.

ответил(а) 2013-02-07T01:58:00+04:00 8 лет назад
60

Я думаю, вы ищете это:

SELECT RecordID, ID1, ID2
FROM yourtable
WHERE ID1 IN (SELECT ID1
FROM yourtable
GROUP BY ID1
HAVING COUNT(DISTINCT ID2)>1);

Смотрите здесь.

ответил(а) 2013-02-07T00:47:00+04:00 8 лет назад
61

Предполагая, что я понимаю ваши требования, я думаю, что все, что вам нужно, это INNER JOIN:

SELECT DISTINCT T.*
FROM YourTable T
JOIN YourTable T2 ON T.ID1 = T2.ID1 AND T.ID2 <> T2.ID2

И вот SQL Fiddle.

Обратите внимание: в этом примере он возвращает все строки из X и Y. X из-за A и B; Y из-за C и D. Правильно ли это?

Удачи.

ответил(а) 2013-02-07T00:45:00+04:00 8 лет назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема