简体   繁体   中英

How to write query to find commalities such as customers who ordered in same dates?

In a single table named orders with columns

OrderID CustomerID  .. OrderDate ..

I am looking for pairs of customers who ordered in same dates and would like to generate a result set such as

CustomerID1 CustomerID2 NumberOfCommonDates 

my best guess so far was this:

SELECT * FROM [Orders]  AS a, [Orders]  AS b  
    WHERE a.OrderDate = b.OrderDate AND a.CustomerID <> b.CustomerID 

Any tips would be appreciated

You could self-join the table and use aggregation:

select
    o1.CustomerID CustomerID1,
    o2.CustomerID CustomerID2,
    count(*) NumberOfCommonDates 
from 
    orders o1
    inner join orders o2 
        on  o1.CustomerID < o2.CustomerID
        and o1.OrderDate = o2.OrderDate 
group by
    o1.CustomerID,
    o2.CustomerID

Join condition o1.CustomerID < o2.CustomerID ensures that you we not joining a record with itself, and also avoids duplicates in the result set like ('customerA', 'customerB') vs ('customerB', 'customerA') .

Note: this assumes that column OrderDate is of DATE datatype. If it's a DATETIME , then you would need to extract the date part before comparing, like:

date(o1.OrderDate) = date(o2.OrderDate)

I am looking for pairs of customers who ordered in same dates and would like to generate a result set such as

CustomerID1 CustomerID2 NumberOfCommonDates

Based on this, you want a self-join and aggregation, similar to other answers. However, you need to be careful about customers who might make multiple orders on the same date.

The correct answer to that question is:

SELECT o1.CustomerID as CustomerID1,
       o2.CustomerID as CustomerID2,
       COUNT(DISTINCT o1.OrderDate) as NumberOfCommonDates
FROM Orders o1 JOIN
     Orders o2  
     ON o1.OrderDate = o2.OrderDate AND
        o1.CustomerID < o2.CustomerID 
GROUP BY o1.CustomerID, o2.CustomerID
ORDER BY NumberOfCommonDates DESC;

The o1.CustomerID < o2.CustomerID is so the same pair of customers does not appear twice.

Based on the comments to other questions, I'm not sure this is what you really want. However, I figured that there should at least be a correct answer to the question you actually asked.

If this is not what you want, I would suggest that you ask a new question and provide sample data, desired results, and a clear explanation of what you want.

Is this what you want?

     SELECT  t.customerid, t1.customerid, 
      Count(distinct *) as numberofdates
      FROM [Orders]  t join Orders t1
     on t.date=t1.date and t.customerid<> 
    t1.customerid group by customerid

@Arzev Mansuri was on the right track. Slightly modified you can get your three columns. and even two more with a first and last common date:

SELECT o1.customer, o2.customer, Count(*) cnt, min(o1.pdate) dmin, case when count(*)>1 THEN max(o1.pdate) END dmax
FROM tbl o1 
inner join tbl o2 on o1.pdate=o2.pdate and o1.customer<o2.customer
group by o1.customer, o2.customer 

Sample output:

customer    customer    cnt dmin                dmax
Ginny       Hagrid      1   03.10.2019 00:00:00 NULL
Ginny       Harry       1   07.10.2019 00:00:00 NULL
Ginny       Hermiony    1   03.10.2019 00:00:00 NULL
Hagrid      Hermiony    1   03.10.2019 00:00:00 NULL
Harry       Ron         2   01.10.2019 00:00:00 01.10.2019 00:00:00

See demo here: https://rextester.com/DUGF43842

You can try with this

SELECT o1.customerid, o2.customerid, Count(*) as commonDates FROM Orders o1 join Orders o2 on o1.orderdate=o2.orderdate  group by o1.customerid, o2.customerid

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM