Это был медленный день для преступления в Готэме, поэтому я обернулся.Может сработать.
Это вряд ли сработает сразу после установки, но оно должно помочь вам начать.
Ваш столбец LAST_UPDATE_DATE
находится на таблице PS_DIR_DEP_DISTRIB
, поэтому мыначну там.Во-первых, вы хотите идентифицировать все записи, которые были обновлены за последние 7 дней, потому что это единственные, которые вас интересуют. На протяжении всего этого я предполагаю, и я, вероятно, ошибаюсь, что естественный ключ длятаблица состоит из EMPLID
, BANK_CD
и ACCOUNT_NUM
.Вы захотите добавить фактический естественный ключ для этих столбцов в нескольких местах.Тем не менее, ограничитель даты выглядит примерно так:
SELECT
EMPLID
,BANK_CD
,ACCOUNT_NUM
FROM
PS_DIR_DEP_DISTRIB AS limit
WHERE
limit.LAST_UPDATE_DATE >= DATEADD(DAY, -7, CAST(GETDATE() AS DATE))
AND
limit.LAST_UPDATE_DATE <= CAST(GETDATE() AS DATE)
Теперь мы будем использовать это как коррелированный подзапрос в предложении WHERE EXISTS
, которое мы сопоставим с базовой таблицей для ограничениясами записи с естественными значениями ключа, которые были обновлены на прошлой неделе.Я изменил список SELECT
на SELECT 1
, что является типичным словосочетанием для коррелированного подпрограммы, так как он прекращает поиск совпадения, когда находит один (1), и фактически не возвращает никаких значений вообще.
Кроме того, поскольку мы все равно фильтруем этот набор записей, я переместил все остальные фильтры предложений WHERE
для этой таблицы в этот (скоро будет) подзапрос.
Наконец, вSELECT
часть, я добавил DENSE_RANK
, чтобы принудительно упорядочить записи.Позже мы используем значение DENSE_RANK
, чтобы отфильтровать только первые ( N ) записи, представляющие интерес.
Так что нам остается следующее:
SELECT
EMPLID
,BANK_CD
,ACCOUNT_NUM
--,ACCOUNT_TYPE --Might belong here. Can't tell without table alias in original SELECT
,PRIORITY
,EFFDT
,LAST_UPDATE_DATE
,DEPOSIT_TYPE
,AMOUNT_PCT
,DENSE_RANK() OVER (PARTITION BY --Add actual natural key columns here...
EMPLID
ORDER BY
LAST_UPDATE_DATE DESC
) AS RowNum
FROM
PS_DIR_DEP_DISTRIB AS sdist
WHERE
EXISTS
(
-- Get the set of records that were last updated in the last 7 days.
-- Correlate to the outer query so it only returns records related to this subset.
-- This uses a correlated subquery. A JOIN will work, too. Try both, pick the faster one.
-- Something like this, using the actual natural key columns in the WHERE
SELECT
1
FROM
PS_DIR_DEP_DISTRIB AS limit
WHERE
--The first two define the date range.
limit.LAST_UPDATE_DATE >= DATEADD(DAY, -7, CAST(GETDATE() AS DATE))
AND limit.LAST_UPDATE_DATE <= CAST(GETDATE() AS DATE)
AND
--And these are the correlations to the outer query.
limit.EMPLID = sdist.EMPLID
AND limit.BANK_CD = sdist.BANK_CD
AND limit.ACCOUNT_NUM = sdist.ACCOUNT_NUM
)
AND
(
dist.DEPOSIT_TYPE = 'P'
AND dist.AMOUNT_PCT = 100
)
OR dist.PRIORITY = 999
OR dist.DEPOSIT_TYPE = 'B'
Замените исходный запрос INNER JOIN
на PS_DIR_DEP_DISTRIB
этим запросом.В списке SELECT
первое жестко закодированное значение теперь зависит от значения RowNum
, так что теперь это выражение CASE
.В предложении WHERE
все даты определяются подзапросом, поэтому они пропали, некоторые из них были свернуты в подзапрос, и мы добавляем WHERE dist.RowNum <= 2
, чтобы вернуть 2 верхние записи.
(я также заменил все псевдонимы таблицы, чтобы я мог отслеживать то, на что я смотрел.)
SELECT
CASE dist.RowNum
WHEN 1 THEN 'NEW ROW'
ELSE 'OLD ROW'
END AS ROW_TYPE
,dist.EMPLID
,emp.FIRST_NAME
,emp.LAST_NAME
,dist.BANK_CD
,dist.ACCOUNT_NUM
,ACCOUNT_TYPE
,dist.PRIORITY
,dist.LAST_UPDATE_DATE
FROM
PS_DIRECT_DEPOSIT AS dd
INNER JOIN
(
SELECT
EMPLID
,BANK_CD
,ACCOUNT_NUM
--,ACCOUNT_TYPE --Might belong here. Can't tell without table alias in original SELECT
,PRIORITY
,EFFDT
,LAST_UPDATE_DATE
,DEPOSIT_TYPE
,AMOUNT_PCT
,DENSE_RANK() OVER (PARTITION BY --Add actual natural key columns here...
EMPLID
ORDER BY
LAST_UPDATE_DATE DESC
) AS RowNum
FROM
PS_DIR_DEP_DISTRIB AS sdist
WHERE
EXISTS
(
-- Get the set of records that were last updated in the last 7 days.
-- Correlate to the outer query so it only returns records related to this subset.
-- This uses a correlated subquery. A JOIN will work, too. Try both, pick the faster one.
-- Something like this, using the actual natural key columns in the WHERE
SELECT
1
FROM
PS_DIR_DEP_DISTRIB AS limit
WHERE
--The first two define the date range.
limit.LAST_UPDATE_DATE >= DATEADD(DAY, -7, CAST(GETDATE() AS DATE))
AND limit.LAST_UPDATE_DATE <= CAST(GETDATE() AS DATE)
AND
--And these are the correlations to the outer query.
limit.EMPLID = sdist.EMPLID
AND limit.BANK_CD = sdist.BANK_CD
AND limit.ACCOUNT_NUM = sdist.ACCOUNT_NUM
)
AND
(
dist.DEPOSIT_TYPE = 'P'
AND dist.AMOUNT_PCT = 100
)
OR dist.PRIORITY = 999
OR dist.DEPOSIT_TYPE = 'B'
) AS dist
ON
dist.EMPLID = dd.EMPLID
AND dist.EFFDT = dd.EFFDT
INNER JOIN
PS_EMPLOYEES AS emp
ON
emp.EMPLID = dist.EMPLID
WHERE
dist.RowNum <= 2
AND
emp.EMPL_STATUS NOT IN ('T', 'R', 'D')
AND
dd.EFF_STATUS = 'A';