#sql-server
#sql-сервер
Вопрос:
Я использую SQL-Server Enterprise версии 8.0. У меня есть этот запрос, который становится невероятно сложным и не дает мне нужных результатов. Запрос выполняется, но я не получаю результатов с добавлением последней даты.
Пока есть три основные проблемы.
В принципе, мне нужно найти повторяющиеся имена в базе данных и идентифицирующую информацию о них. Предпочтительно, я хотел бы поместить столбцы с повторяющимися именами и адресами рядом друг с другом, чтобы их можно было сравнивать столько раз, сколько они появляются в базе данных. Итак, если имя в базе данных повторяется 3 раза, я бы хотел, чтобы там было имя C1, имя C2 и имя C3.
Я также хотел бы присоединиться к другим таблицам, чтобы я мог получить такую информацию, как имя дочернего элемента и какое последнее действие (подзапрос) было на клиенте.
Проблема № 1: естественное соединение здесь не работает в сочетании с левыми внешними соединениями. Нужно ли мне использовать объединение?
Проблема № 2: Я пытаюсь получить самую последнюю активность. В то время как Case ..When работает самостоятельно, при вводе вместе с остальной частью запроса (за вычетом левых внешних соединений) не дает никаких результатов. В идеале я бы хотел, чтобы для каждого контакта возвращалось самое последнее действие, C1 и C2 в выборе. Я использовал contactid, но, возможно, это не то, что я должен использовать?
Проблема № 3: Если имя появляется в базе данных более 2 раз, я получаю всевозможные комбинации для них в разных строках. Как я могу заставить их отображаться в списке результатов в виде одной строки, а не нескольких комбинаций? Нужно ли добавлять C3? Существует целых 7 и 8 повторяющихся имен .. как мне не допустить, чтобы запрос становился более громоздким? Есть ли какие-либо другие способы сделать это?
Чтобы привести пример, я бы хотел, чтобы результаты отображались как таковые:
‘ContactID 1’, ‘ContactID 2’, ‘ContactID 3’, ‘Фамилия’, ‘Имя’, ‘Адрес контакта 1’, ‘Адрес контакта 2’, ‘Адрес контакта 3’, ‘Домашний телефон C1 и рабочий телефон’, ‘Домашний телефон C2 и рабочий телефон’, ‘Домашний телефон C3 и рабочий телефон’, ‘Имя ребенка C1’, ‘Имя ребенка C2’, ‘Имя ребенка C3’, ‘Последнее действие C1’, «C2 Самое последнее действие», «C3 самое последнее действие»
Я бы сократил запрос до базовых, чтобы упростить его, но на данный момент я не знаю, что опустить. Простите за громоздкий запрос, и я ценю, что вы нашли время:
SELECT DISTINCT (c1.contactid) as 'ContactID 1', (c2.contactid) as 'ContactID 2', c1.lastname as
'Last Name', c1.firstname as 'First Name',
(c1.address ' ' c1.city ', ' c1.state ' ' c1.postalcode) as 'Contact 1 Address',
(c2.address ' ' c2.city ', ' c2.state ' ' c2.postalcode) as 'Contact 2 Address',
(c1.homephone ' ' c1.workphone) as 'C1 Home phone and Work phone',
(c2.homephone ' ' c2.workphone) as 'C2 Home phone and Work phone',
(cg.childfirst ' ' cg.childlast) as 'C1 Child''s Name',
(cv.childfirst ' ' cv.childlast) as 'C2 Child''s Name'
FROM contacts c1, contacts c2
WHERE (c1.child=0) and (c1.contactid<c2.contactid) and ((c1.lastname c1.firstname)=
(c2.lastname c2.firstname))
LEFT OUTER JOIN caregiverlabel cg on c1.contactid=cg.contactid,
contacts c2
LEFT OUTER JOIN caregiverlabel cv on c2.contactid=cv.contactid
AND c1.contactid IN
(SELECT max(MostRecentActivity)
FROM (select case
WHEN c1.modifieddate >= sl.starttime AND c1.modifieddate >= cl.createdate
AND c1.modifieddate >= pr.created AND c1.modifieddate >= pm.created THEN
c1.modifieddate
WHEN sl.starttime >= c1.modifieddate AND sl.starttime >= cl.createdate AND
sl.starttime >= pr.created AND sl.starttime >= pm.created THEN sl.starttime
WHEN cl.createdate >= c1.modifieddate AND cl.createdate >= sl.starttime AND
cl.createdate >= pr.created AND cl.createdate >= pm.created THEN
cl.createdate
WHEN pr.created >= c1.modifieddate AND pr.created >= sl.starttime AND
pr.created >= cl.createdate AND pr.created >= pm.created THEN pr.created
WHEN pm.created >= c1.modifieddate AND pm.created >= sl.starttime AND
pm.created >= cl.createdate AND pm.created >= pr.created THEN pm.created
ELSE c1.modifieddate
END AS MostRecentActivity
FROM contacts c1
left outer join serviceslabel sl on c1.contactid=sl.contactid
left outer join calls cl on c1.contactid=cl.contactid
left outer join procall pr on c1.contactid=pr.contactid
left outer join pmpcall pm on c1.contactid=pm.contactid
) AS date_query
)
order by c1.lastname, c1.firstname
Комментарии:
1. Если под тегами
sql
иserver
вы имеете в видуsql-server
? Если да, можете ли вы обновить в своем сообщении версию SQL Server, которую вы используете?2. Да, это SQL Server. Я не знаю, почему теги разделены, поскольку я записал их вместе. Я попытаюсь отредактировать.
3. Как насчет версии SQL Server?
4. @Thomas — Это SQL-Server Enterprise версии 8.0. Я также отредактирую текст вопроса. Спасибо!
Ответ №1:
Отправляемый вами запрос слишком сложен для нас. Никто не потратит время на его расшифровку. Однако вот как вы получаете все повторяющиеся строки:
выберите * из T join (выберите col1, col2 из T group по col1, col2 с количеством (*) > 1) дубликатов на T.col1 = dups.col1 и …
Хитрость заключается в том, чтобы сначала найти дубликаты «ключей», а затем найти все строки, в которых есть один из дубликатов ключей.
Комментарии:
1. Да, спасибо за ваш ответ и обратную связь. Я попробую этот способ и, возможно, отправлю более простой запрос для последнего действия.
2. @usr — Теперь понял. Он работает для поиска дубликатов, и я не знал, что вы можете присоединиться подобным образом. Спасибо!