1

If I have following table in Postgres:

order_dtls

Order_id    Order_date  Customer_name
-------------------------------------
1           11/09/17    Xyz
2           15/09/17    Lmn
3           12/09/17    Xyz
4           18/09/17    Abc
5           15/09/17    Xyz
6           25/09/17    Lmn
7           19/09/17    Abc

I want to retrieve such customer who has placed orders on 2 consecutive days. In above case Xyz and Abc customers should be returned by query as result.

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228

5 Answers5

1

There are many ways to do this. Use an EXISTS semi-join followed by DISTINCT or GROUP BY, should be among the fastest.

Postgres syntax:

SELECT DISTINCT customer_name
FROM   order_dtls o
WHERE  EXISTS (
   SELEST 1 FROM order_dtls
   WHERE  customer_name = o.customer_name
   AND    order_date = o.order_date + 1  -- simple syntax for data type "date" in Postgres!
   );

If the table is big, be sure to have an index on (customer_name, order_date) to make it fast - index items in this order.

To clarify, since Oto happened to post almost the same solution a bit faster:

DISTINCT is an SQL construct, a syntax element, not a function. Do not use parentheses like DISTINCT (customer_name). Would be short for DISTINCT ROW(customer_name) - a row constructor unrelated to DISTINCT - and just noise for the simple case with a single expression, because Postgres removes the pointless row wrapper for a single element automatically. But if you wrap more than one expression like that, you get an actual row type - an anonymous record actually, since no row type is given. Most certainly not what you want.

Also, don't confuse DISTINCT with DISTINCT ON (expr, ...). See:

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
0

This should work:

SELECT A.customer_name
    FROM order_dtls A
    INNER JOIN (SELECT customer_name, order_date FROM order_dtls) as B
    ON(A.customer_name = B.customer_name and Datediff(B.Order_date, A.Order_date) =1)
    group by A.customer_name
iLikeMySql
  • 736
  • 3
  • 7
0

The way I would think of it doing it would be to join the table the date part with itselft on the next date and joining it with the Customer_name too. This way you can ensure that the same customer_name done an order on 2 consecutive days.

For MySQL:

SELECT distinct *
FROM order_dtls t1
    INNER JOIN order_dtls t2 on
            t1.Order_date = DATE_ADD(t2.Order_date, INTERVAL 1 DAY) and
            t1.Customer_name = t2.Customer_name

The result you should also select it with the Distinct keyword to ensure the same customer is not displayed more than 1 time.

0

Try something like...

SELECT `order_dtls`.*
FROM `order_dtls`
INNER JOIN `order_dtls` AS mirror
ON `order_dtls`.`Order_id` <> `mirror`.`Order_id`
AND `order_dtls`.`Customer_name` = `mirror`.`Customer_name`
AND DATEDIFF(`order_dtls`.`Order_date`, `mirror`.`Order_date`) = 1
SubjectDelta
  • 405
  • 1
  • 3
  • 14
0

For postgresql:

select distinct(Customer_name) from your_table
where exists 
    (select 1 from your_table t1 
    where 
    Customer_name = your_table.Customer_name and Order_date = your_table.Order_date+1 )

Same for MySQL, just instead of your_table.Order_date+1 use: DATE_ADD(your_table.Order_date , INTERVAL 1 DAY)

Oto Shavadze
  • 40,603
  • 55
  • 152
  • 236