Необходимы дубликаты, а также последняя дата

#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 — Теперь понял. Он работает для поиска дубликатов, и я не знал, что вы можете присоединиться подобным образом. Спасибо!