Мой мозг слишком утомлен, чтобы в данный момент найти реальный запрос на это, но я мог бы дать вам толчок в пути, который должен работать:)
Что если вы добавите еще один столбец (может быть, вместо таблицы действительных дублированных пользователей? ... оба выполнят одно и то же), и запустите подзапрос, который подсчитает все допустимые дубликаты, и затем вы сможете сравнить с количество в вашем текущем запросе. Вы исключили бы всех пользователей, у которых есть совпадающее число, и включили бы любого с числом, которое выше. Надеюсь, это имеет смысл; Я создам вариант использования:
- Крис Бейкер с id 1 и 4 помечен как valid_duplicates
- В системе 4 Криса Бейкера
- Вы получаете количество действительных Крис Бейкер
- Вы получаете счет всех Крис Бейкер
- valid_count <> total_count, поэтому верните Криса Бейкера
* Вы, вероятно, даже можете изменить запрос так, чтобы он даже не перечислял дублирующиеся идентификаторы (даже если вы получаете дублирующую маркировку только 1 идентификатора). Вместо того, чтобы перепроверить, какие из них действительны. Это было бы немного сложнее. Без этого, по крайней мере, вы игнорируете Криса Бейкера, пока другой не войдет в систему
Я написал базовый запрос, касающийся исключения конкретных идентификаторов, которые я попытаюсь ввести сегодня вечером. Но это, по крайней мере, решает ваши первоначальные потребности. Если вам не нужен более сложный запрос, дайте мне знать, чтобы я не тратил на него свое время:)
SELECT
GROUP_CONCAT(id) AS "ids",
CONCAT(UPPER(first_name), UPPER(last_name)) AS "name",
COUNT(*) AS "duplicate_count"
FROM
users
WHERE NOT EXISTS
(
SELECT 1
FROM
(
SELECT
CONCAT(UPPER(first_name), UPPER(last_name)) AS "name",
COUNT(*) AS "valid_duplicate_count"
FROM
users
WHERE
is_valid_duplicate = 1 --true
GROUP BY
name
HAVING
valid_duplicate_count > 1
) AS duplicate_users
WHERE
duplicate_users.name = users.name
AND valid_duplicate_count = duplicate_count
)
GROUP BY
name
HAVING
duplicate_count > 1
Ниже приведен запрос о том, что должен сделать то же, что и выше, но в окончательном списке будут напечатаны только идентификаторы, которых нет в допустимом списке. Это на самом деле оказалось намного проще, чем я думал. И, в основном, это то же самое, что и выше, но единственная причина, которую я оставил выше, - это оставить два варианта, и в случае, если я испортил вышеупомянутое ... это действительно сложно, так как это много вложенных запросов. Если вам доступны CTE или даже временные таблицы. Это может сделать запрос более выразительным, чтобы разбить его на временные таблицы :). Надеюсь, это поможет и то, что вы ищете
SELECT GROUP_CONCAT(id) AS "ids",
CONCAT(UPPER(first_name), UPPER(last_name)) AS "name",
COUNT(*) AS "final_duplicate_count"
--This count could actually be 1 due to the nature of the query
FROM
users
--get the list of duplicated user names
WHERE EXISTS
(
SELECT
CONCAT(UPPER(first_name), UPPER(last_name)) AS "name",
COUNT(*) AS "total_duplicate_count"
FROM
users AS total_dup_users
--ignore valid_users whose count still matches
WHERE NOT EXISTS
(
SELECT 1
FROM
(
SELECT
CONCAT(UPPER(first_name), UPPER(last_name)) AS "name",
COUNT(*) AS "valid_duplicate_count"
FROM
users AS valid_users
WHERE
is_valid_duplicate = 1 --true
GROUP BY
name
HAVING
valid_duplicate_count > 1
) AS duplicate_users
WHERE
--join inner table to outer table
duplicate_users.name = total_dup_users.name
--valid count check
AND valid_duplicate_count = total_duplicate_count
)
--join inner table to outer table
AND total_dup_users.Name = users.Name
GROUP BY
name
HAVING
duplicate_count > 1
)
--ignore users that are valid when doing the actual counts
AND NOT EXISTS
(
SELECT 1
FROM users AS valid
WHERE
--join inner table to outer table
users.name =
CONCAT(UPPER(valid.first_name), UPPER(valid.last_name))
--only valid users
AND valid.is_valid_duplicate = 1 --true
)
GROUP BY
FinalDuplicates.Name