Внутренний Объединение нескольких таблиц, но хотите, чтобы отдельные данные основывались на одном столбце - PullRequest
0 голосов
/ 17 октября 2019

Общие сведения из-за работы, но здесь не хватает.

В настоящее время мы размещаем клиентов, адреса клиентов, электронные письма клиентов во всех отдельных таблицах. Я пытаюсь запустить отчет, в котором я внутренне объединяю эти таблицы, но хочу, чтобы он предоставил отличные результаты только на основе таблицы клиентов. Проблема, с которой я сталкиваюсь, заключается в том, что он по-прежнему возвращает кратные числа, потому что кто-то, возможно, обновил электронное письмо и вставил новую запись

Пробовал перемещать DISTINCT, а также делать предложение "Group By", но ни один из них не являетсявозвращая правильные результаты. Есть столбец «последнего изменения», так что, может быть, я могу получить результаты только с самыми последними изменениями?

Т.е. Чарльз Смит как 3 строки Джон Смит 4 строки и т. Д. Могу ли я установить измененный оператор так, чтобы он возвращал толькоПоследнее изменение из этих?

select
c.customer_id
c.first_name
c.last_name
ce.email_address
ca.addr_street
ca.addr_city
ca.addr_zip
FROM Customers C
INNER JOIN Cust_Address ca ON c.cust_id=ca.addr_cust_id
Inner JOIN Cust_Email ce ON c.cust_id=ce.email_cust_id

Я хочу, чтобы он возвращал только одну запись для каждого клиента, независимо от того, сколько адресов / электронных писем у них в системе.

Ответы [ 2 ]

0 голосов
/ 17 октября 2019

Если, как указано в вопросе, дубликаты взяты из cust_email, и, поскольку вы показываете один столбец из этой таблицы в наборе результатов, решение будет состоять в том, чтобы удалить его из объединения и использовать встроенный запрос впредложение select выглядит следующим образом:

select
    c.customer_id
    c.first_name
    c.last_name
    (
        select email_address 
        from cust_email ce 
        where c.cust_id = ce.email_cust_id 
        order by ce.last_modified desc 
        limit 1
    ) email_address
    ca.addr_street
    ca.addr_city
    ca.addr_zip
from 
    customers c
    inner join cust_address ca on c.cust_id=ca.addr_cust_id

В этом решении используется предложение limit (поддерживается, в частности, в MySQL и Postgres);синтаксис может варьироваться в зависимости от вашей СУБД (обычно SQLServer и Oracle имеют разный синтаксис).

При индексе cust_email(cust_id) это должно быть эффективным решением, которое устраняет необходимость в оконных функциях.

0 голосов
/ 17 октября 2019

Использование row_number() и подзапросов:

SELECT c.customer_id, c.first_name, c.last_name,
       ce.email_address, ca.addr_street, ca.addr_city ca.addr_zip
FROM Customers C INNER JOIN
     (SELECT ca.*,
             ROW_NUMBER() OVER (PARTITION BY addr_cust_id ORDER BY lastmodified DESC) as seqnum
      FROM Cust_Address ca
     ) ca
     ON c.cust_id = ca.addr_cust_id INNER JOIN
     (SELECT ce.*,
             ROW_NUMBER() OVER (PARTITION BY email_cust_id ORDER BY lastmodified DESC) as seqnum
      FROM Cust_Email ce
     ) ce
     ON c.cust_id = ce.email_cust_id
WHERE ca.seqnum = 1 AND ce.seqnum = 1;
...