Сравните данные в двух таблицах
У меня есть две таблицы, которые мне нужно сравнить, чтобы убедиться, что значения совпадают. Для контекста один - это табель рабочего времени сотрудника, а другой - таблица для хранения их запросов. У каждого есть код табеля рабочего времени и количество часов. Мой план состоял в том, чтобы сравнить по сводке, чтобы увидеть, совпадают ли они. Однако у меня возникают проблемы с тем, чтобы моя логика работала идеально каждый раз. Если бы я не опубликовал свой код (он быстро превращается в беспорядок), как бы вы подошли к этому? Сравнение должно выполняться программно и, в конце концов, возвращать true/false.
Это может быть решение RPG или решение SQL.
Это то, что мне нужно, чтобы убедиться, что это правда.
Table 1
02 1.5
04 16.0
Table 2
02 1.5
04 16.0
Проблема в том, когда
Table 1
02 1.5
Table 2
02 1.5
04 16.0
или когда
Table 1
02 1.5
04 16.0
Table 2
02 1.5
или больше, когда
Table 1
02 1.5
04 16.0
Table 2
6 ответов
Я поместил два моих результата SQL в представления, тогда основанные на обратной связи многих людей, уже придумали это. Я думаю, что это может быть создано в свою собственную хранимую процедуру.
SELECT SUM ( ERROR_COUNT ) AS TOTAL_ERRORS INTO NUM_ERRORS FROM (
SELECT COUNT ( * ) AS ERROR_COUNT
FROM MPRLIB . V_TSHOURSUMM A EXCEPTION JOIN MPRLIB . V_REQHOURSUMM B
ON A . EM_NUMBER = B . EM_NUMBER AND A . TIMESHEET_CODE = B . TIMESHEET_CODE AND A.HOURS_SUMMARY = B . HOURS_SUMMARY
WHERE A . EM_NUMBER = EMPLOYEE_ID OR B . EM_NUMBER = EMPLOYEE_ID
UNION
SELECT COUNT ( * ) AS ERROR_COUNT
FROM MPRLIB . V_REQHOURSUMM A EXCEPTION JOIN MPRLIB . V_TSHOURSUMM B
ON A . EM_NUMBER = B . EM_NUMBER AND A . TIMESHEET_CODE = B . TIMESHEET_CODE AND A . HOURS_SUMMARY = B . HOURS_SUMMARY
WHERE A . EM_NUMBER = EMPLOYEE_ID OR B . EM_NUMBER = EMPLOYEE_ID ) TABLE
Кажется, работает, но кажется... чрезмерным. Мысли? Есть ли способ лучше?
Это должно дать запрошенные результаты:
with w1 ( wid, sumHrs )
as ( SELECT id, sum(hours)
FROM A a1
GROUP BY id ),
w2 ( wid, sumHrs )
as ( SELECT id, sum(hours)
FROM B b1
GROUP BY id )
select '1', w1.wid from w1 INNER JOIN w2
on w1.wid = w2.wid
where w1.sumHrs <> w2.sumHrs
union
select '2', w1.wid from w1 EXCEPTION JOIN w2
on w1.wid = w2.wid
union
select '3', w2.wid from w2 EXCEPTION JOIN w1
on w2.wid = w1.wid
Могут быть незначительные изменения в деталях, необходимые из-за адаптации и упрощения из моего примера, который близок, но не точен. Все основные понятия должны быть ясными.
CTE дает пару сводных "представлений" для использования в полном утверждении. INNER JOIN
дает соответствующие идентификаторы с несовпадающими часами. Первый EXCEPTION JOIN
дает строки из первой таблицы без совпадающего идентификатора во второй таблице, а вторая EXCEPTION JOIN
дает строки, которые не совпадают в другом направлении. И UNIONs
собрать все результаты вместе.
Это будет сравнивать общее количество часов в A и B для каждого значения идентификатора, и только возвращать записи, где сумма B не равна A. Он рассматривает несопоставленные значения B как ноль.
SELECT A.id, A.hours, SUM(COALESCE(B.Hours,0))
FROM A
LEFT OUTER JOIN B
ON B.ID = A.ID
WHERE 1=1
AND A.id = B.id
GROUP BY A.id
HAVING A.Hours != SUM(COALESCE(B.Hours,0))
Cheers,
Daniel
В общем случае, если вы объединяете две таблицы, и количество итоговых таблиц совпадает с количеством отдельных таблиц, вы можете сказать, что они имеют одинаковые значения.
Я не уверен, как подать заявку в вашем случае, но, возможно, вы можете.
Недавно я сделал что-то подобное - вот мои заметки... результирующий набор показывает различия в значениях плюс строки, которые присутствуют в одной таблице, но не в другой.
Шаг 1: Создайте временные таблицы, содержащие строки, которые вы хотите сравнить.
Шаг 2: Выполните FULL OUTER JOIN для временных таблиц, используя неагрегированные столбцы в качестве критерия соответствия.
DECLARE @Ta TABLE (PubA varchar(255), CampA varchar(255), RevA money)
INSERT INTO @Ta (PubA, CampA, RevA)
SELECT Publisher, [Campaign Name], SUM([Revenue USD])
FROM D1.dbo.Stats
GROUP BY Publisher, [Campaign Name]
DECLARE @Tb TABLE (PubB varchar(255), CampB varchar(255), RevB money)
INSERT INTO @Tb (PubB, CampB, RevB)
SELECT Publisher, [Campaign Name], SUM([Revenue USD])
FROM D2.dbo.Stats
GROUP BY Publisher, [Campaign Name]
SELECT PubA, CampA, RevA, PubB, CampB, RevB, RevA-RevB DiffRev
FROM @Ta
FULL OUTER JOIN @Tb
ON PubA=PubB and CampA=CampB
ORDER BY DiffRev DESC
GO
Самое простое решение - показать конфликтующие строки:
CREATE TABLE requests ( employees_id integer, hours decimal );
CREATE TABLE hours ( employees_id integer, hours decimal );
SELECT * FROM requests, hours WHERE requests.employees_id = hours.employees_id AND requests.hours != hours.hours;
Но это не работает, если, например, один 2-часовой запрос должен соответствовать двум 1-часовым отметкам.