1

I have a contacts table that is like this:

|id|first_name|last_name|date_entered|

then, I have a table that stores the email addresses like this:

|id|email_address|

I then have a relational table that joins the two tables above together like this:

|id|contact_id|email_id|

What I am trying to figure out is, how do I get a count of all new contacts that has been entered in between 2023-02-10 and 2023-02-13 but only the contacts that have matching emails?

For example, a new contact is entered in the db with the email of [email protected]. A few days later, that same contact comes back and is entered in by another person but with the same email address of [email protected].

I am building a report of "New vs Returning Customers" and we use their email to identify a customer that is returning. So, I am needing to be able to list a count of all customers in the database with the same email that is > 1. Is this possible with MySQL? Thanks!

4
  • Please consider following these suggestions.
    – mustaccio
    Commented Feb 13, 2023 at 20:39
  • I'm not sure I understand what I left out? I thought I was being fairly thorough with my question. But, I edited a couple of mistakes I noticed above just in case. Thank you for the feedback.
    – swhitlow
    Commented Feb 13, 2023 at 21:37
  • Your question arguably addresses the first point from the linked post, but not points 2, 3, and 6. If you make it easier for people to reproduce your data and see the results you expect, it will also make it easier for them to post a good answer.
    – mustaccio
    Commented Feb 13, 2023 at 21:46
  • The title sounds like you need a "self join".
    – Rick James
    Commented Feb 14, 2023 at 23:27

1 Answer 1

1

Perhaps something like this

SELECT C.first_name,C.last_name,CE.contact_id,E.email_address
FROM contacts_emails CE
INNER contacts C ON CE.contact_id = C.id
INNER JOIN emails E ON CE.email_id = E.id
WHERE C.date_entered >= '2023-02-10 00:00:00'
AND   C.date_entered <= '2023-02-13 23:59:59';

Now to identify new verses returning

SELECT
    C.first_name
   ,C.last_name
   ,CE.contact_id
   ,E.email_address
   ,IF(EC.emailcnt=1,'New','Returning') NewOrReturning
FROM contacts_emails CE
INNER contacts C ON CE.contact_id = C.id
INNER JOIN emails E ON CE.email_id = E.id
INNER JOIN
(
    SELECT email_address,COUNT(1) emailcnt
    FROM emails GROUP BY email_address
) EC ON E.email_address = EC.email_address
WHERE C.date_entered >= '2023-02-10 00:00:00'
AND   C.date_entered <= '2023-02-13 23:59:59';

This is just a start. Hope this helps.

6
  • This is great! This got me "super" close. I just had to change up the subquery. But, I am having two issues with this: 1. It is very, very slow to run for some reason. Not sure if there is a way to speed it up? 2. it is not giving me the "Returning" count that I needed. It does list all of the new and returning. But, I was needing the counts of new vs returning. Any suggestions?
    – swhitlow
    Commented Feb 14, 2023 at 20:14
  • Here is the updated query I have (with the leads table): SELECT l.first_name ,l.last_name ,e.email_address ,IF(EC.emailcnt>1,'Returning','New') NewOrReturning FROM leads l INNER JOIN email_addr_bean_rel er ON er.bean_id = l.id INNER JOIN email_addresses e ON er.email_address_id = e.id INNER JOIN ( SELECT email_address_id,COUNT(1) emailcnt FROM email_addr_bean_rel GROUP BY email_address_id ) EC ON e.id = EC.email_address_id where l.date_entered >= '2023-02-12 06:00:00' AND l.date_entered < '2023-02-13 19:38:56' and l.deleted = '0';
    – swhitlow
    Commented Feb 14, 2023 at 20:17
  • Do you have an index on the date_entered column in the contacts table ??? If you don't, then index it with ALTER TABLE contacts ADD INDEX idx_date_entered (date_entered); Commented Feb 14, 2023 at 21:15
  • Yes, I have an index on that table for date_entered.
    – swhitlow
    Commented Feb 14, 2023 at 22:43
  • any thoughts or suggestions on how to get the count for new and returning instead of just returning the entire list? Here is the SQL statement that is working that you provided (it is just listing everything instead of showing the count). Thanks so much for you help!
    – swhitlow
    Commented Feb 15, 2023 at 15:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.