Вопрос или проблема
Надеюсь, кто-то сможет помочь с запросом ниже, где я застрял.
У меня есть таблица настроек (основанная на штате, городе и округе), где * в настройках обозначает “все”, в противном случае оно представляет собой конкретное значение, которое оно имеет. Мне нужно извлечь данные из основной таблицы, объединив их с таблицей настроек, чтобы он только получал население, как определено в таблице настроек.
Штат | Город | Округ |
---|---|---|
AZ | * | * |
CA | * | Лос-Анджелес |
CA | Сан-Диего | * |
CA | Сан-Франциско | * |
CA | Санта-Моника | * |
NY | * | * |
NY | * | Бронкс |
NY | * | Кингс |
Основная таблица – это таблица “person”, которая имеет столбцы штат, город и округ с фактическими значениями местоположения человека. Мне нужно объединить это с таблицей настроек, чтобы она только выбирала применимые строки, где * в таблице настроек представляет “все”. Штат всегда будет иметь допустимое значение и никогда не будет *
Исходя из вышеуказанной таблицы настроек, запрос должен извлечь
а) Все из штатов NY и AZ (поскольку в обоих случаях стоит * в городе и округе)
b) из CA – все, относящиеся к городам Сан-Диего, Сан-Франциско и Санта-Моника, а также все, относящиеся к округу Лос-Анджелес.
Я получаю дубликаты в текущем запросе (ниже). Я пробовал несколько вариантов, например, использовать DISTINCT в финальном запросе, чтобы исключить дубликаты, или рассмотреть другие данные, которые можно использовать вместо этого.
SELECT
e.emplid,
e.first_name,
e.last_name ,
e.state,
e.county,
e.city
FROM
person e
JOIN setup S
ON e.state = S.State
AND (e.city = S.city OR S.city = '*')
AND (e.county = S.county OR S.county = '*')
AND sysdate between S.eff_dt and S.end_eff_dt
WHERE
sysdate between e.eff_dt and e.end_eff_dt
AND e.hr_Status <> 'T'
AND e.STAFF = 'N'
And e.union = 'NU'
AND e.country = 'USA';
Ответ или решение
Для извлечения данных на основе комбинации штатов, городов и округов, вам необходимо корректно выполнить JOIN между основной таблицей "person" и таблицей "setup". Данная задача предполагает, что присутствует необходимость учитывать условия, при которых ‘*’ в таблице "setup" означает, что допустимы все значения для соответствующей категории (город или округ).
Основная структура SQL-запроса
Ваш изначальный запрос выглядит логично, но может приводить к дублированию данных, так как обрабатываются элементы, которые могут соответствовать множественным условиям. Основной принцип заключается в том, чтобы правильно построить условия JOIN и учитывать все случаи ‘*’ как литералы для выбора всех возможных значений.
Оптимизированный SQL-запрос
Вот переработанный вариант вашего запроса:
SELECT DISTINCT
e.emplid,
e.first_name,
e.last_name,
e.state,
e.county,
e.city
FROM
person e
JOIN
setup s ON e.state = s.state
WHERE
(
(e.city = s.city OR s.city = '*')
AND (e.county = s.county OR s.county = '*')
)
AND sysdate BETWEEN s.eff_dt AND s.end_eff_dt
AND sysdate BETWEEN e.eff_dt AND e.end_eff_dt
AND e.hr_Status <> 'T'
AND e.STAFF = 'N'
AND e.union = 'NU'
AND e.country = 'USA';
Объяснение изменений
-
Использование DISTINCT: Включить
DISTINCT
в ваш SELECT поможет избавиться от дубликатов, которые могут возникать из-за множества совпадений в таблице "setup" для одной записи в таблице "person". -
Условия соединения: Убедитесь, что условия соединения не создают лишние пересечения. В данном случае, условия для города и округа расположены в WHERE, чтобы структура была более понятной и избегались лишние совпадения.
-
Проверка времени действия: Убедитесь, что используете правильный временной интервал для актуальных записей как в таблице "setup", так и в главной таблице. Это гарантирует, что выборка будет актуальной.
Итог
Данный подход позволит вам эффективно извлекать необходимые данные без дублирования. Важно отметить, что если вы продолжаете сталкиваться с дубликатами, стоит исследовать данные в таблице "person" и определять, возможны ли различные записи для одной и той же комбинации штат/город/округ. Так вы сможете выявить причину возникновения повторяющихся записей.