Find customers who ordered in the last week every day? [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Recently i was asked a question in the interview. Which is there is a customer table and an order table. How to get the customers who ordered in the last week everyday and how to find the customers who order in last three consecutive days?
Appreciate your help.
Thanks in advance.

To get customers who ordered every day for the past N days I would try something like:
select customer_id
from orders
where trunc(order_date) > trunc(sysdate) - :N
group by customer_id
having count(distinct trunc(order_date)) = :N
The idea is that the WHERE clause limits your data to orders made within the last N days, then we GROUP BY to form a group for each customer, and then in the HAVING clause we check each customer to see if COUNT(DISTINCT TRUNC(ORDER_DATE)) equals N.

One way is to convert the order table to a wide table with columns corresponding to each day of interest. Not sure if there are better ways.

A brute force method uses exists. For instance, for the last three days:
select c.*
from customers c
where exists (select 1
from orders o
where o.customer_id = c.customer_id and
trunc(o.order_date) = trunc(sysdate)
) and
exists (select 1
from orders o
where o.customer_id = c.customer_id and
trunc(o.order_date) = trunc(sysdate) - interval '1' day
) and
exists (select 1
from orders o
where o.customer_id = c.customer_id and
trunc(o.order_date) = trunc(sysdate) - interval '2' day
) ;
This is one method. There are others, that I'll let you think about.

Related

attendance system CHECK-IN & CHECK-OUT values in SQL SERVER [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 22 days ago.
This post was edited and submitted for review 22 days ago.
Improve this question
I have an SQL table where I have employee logs and the states of the log state 255 being (check-in) and state 1 being checked-out
I want to have the minimum check-in time and the max checkout time of each day date as a result.
This is the table that I have.
This is the Query
select [full name],
(SELECT MIN(time) AS CHECKIN FROM attendance WHERE state = 255 and fingerprint = id) checkin,
(SELECT MAX(time) AS CHECKIN FROM attendance WHERE state = 1 and fingerprint = id) checkout,
cast (date as date)
FROM employee full outer join attendance on fingerprint = id
group by id,fingerprint,[full name],date
The problem is that it selects the minimum and Max time but not by date
it basically searches the min and max times across all dates instead of each day as its own
notice how it gave the checkin (2:00) and checkout(8:00) for Jon considering the fact that dates are in diffrent years
Is the query good, or am I doing it wrong?
Your query is almost correct, the mistake is that the group by clause in your query groups by id and then fingerprint and groups further by [full name] and then by date. Instead, you need to group only by [full name] and date:
select [full name],
MIN(
CASE
WHEN state = 255 and fingerprint = id THEN time
ELSE 999999
END
) checkin,
MAX(
CASE
WHEN state = 1 and fingerprint = id THEN time
ELSE -1
END
) checkout,
cast (date as date)
FROM employee full outer join attendance on fingerprint = id
group by [full name],date

Count distinct monthly running total [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 12 months ago.
Improve this question
I am trying to find a SQL query to the question of finding the running unique count of distinct customers each month.
This is not the number of distinct customers each month, but rather what is the new incremental total number of unique customers as each month rolls by.
For example, in January I had 10 unique customers and in February I had another 10 customers, but 5 of these who transacted in February were repeat customers and had also transacted in January; so between January and February I really only have a running total of 15 unique customers (10 in January and 5 in February).
What would be the simplest solution to achieve the running unique customer count for each month of the year?
Example Output where (compared to January) in February there were an additional 5 unique customers and in March there were an additional 10 unique customers
This might do:
Select
month,
count(*) as custs,
(select
count(distinct cust_id)
from mytable b
where b.month<=a.month) as RunningUniqueCusts
From mytable a
group by month
Or for month & region
Select
month,
region,
count(*) as custs,
(select
count(distinct cust_id)
from mytable b
where b.month<=a.month
and b.region=a.region) as RunningUniqueCustsForRegion
From mytable a
group by month, region
Update 3-Mar-2022
The following would return the unique customer ids for each month where they didn't appear previously:
SELECT TM.MONTH_ID, TM.CUST_ID
FROM MYTABLE as TM
WHERE NOT EXISTS
(SELECT 1
FROM MYTABLE as PM
WHERE PM.CUST_ID = TM.CUST_ID
and PM.MONTH < TM.MONTH)
GROUP BY TM.MONTH_ID, TM.CUST_ID
ORDER BY TM.MONTH_ID, TM.CUST_ID

How to retrieve the minimum date having 3 columns (day), (month) and (year) with RSQLite? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am working with SQL in R. I want to get the minimum date by choosing the minimum value of the column 'day;, the minimum value of the column 'month' and the minimum value of the column 'year'.
I have tried this by the following code:
dbGetQuery(db, "SELECT day, month, year
FROM surveys
WHERE year = (SELECT MIN(year) FROM surveys);")
But my output is not one value, how can I get one value in my output and not a list of values?
Right now your query returns rows on the minimum year, not minimum date. Consider generating a date column by concatenating the date parts to identify minimum:
sql = "WITH sub AS (
SELECT day, month, year
, DATE(year || '-' ||
CASE
WHEN length(month)=1
THEN '0' || month
ELSE month
END || '-' ||
CASE
WHEN length(day)=1
THEN '0' || day
ELSE day
END) AS [date]
FROM surveys
)
SELECT DISTINCT day, month, year, [date]
FROM sub
WHERE [date] = (SELECT MIN([date]) FROM sub)"
dbGetQuery(db, sql)
Online Demo
Using the test data shown we order it by year, month and day and select the first row of the sorted table.
library(sqldf)
surveys <- data.frame(year = 2001:2005, month = 5:1, day = 1:5)
sqldf("select day, month, year from surveys order by year, month, day limit 1")
## day month year
## 1 1 5 2001

how to get recent 6 dates (Max dates) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I need recent 6 dates count
My code is
select DUE_DATE, count(*)
from DATA
group by DUE_DATE
03/24/2018 10
03/17/2018 20
03/10/2018 15
03/03/2018 23
02/24/2018 42
02/17/2018 32
02/10/2018 15
02/03/2018 17
01/27/2018 23
select DUE_DATE, count(*) from DATA group by DUE_DATE order by DUE_DATE desc limit 6
The simplest case would be if every date is presented and/or you're only interested in 6 most recent dates regardless of whether they're presented in your table or not:
select DUE_DATE, count(*)
from DATA
where DUE_DATE >= trunc(sysdate) - 5
group by DUE_DATE
order by DUE_DATE desc
(Note: dates that are not presented in your table won't be shown).
On the other hand, if you need 6 most recent dates from the subgroup of dates you have in your table, then you'll first need a subquery to fetch you those dates and than use count on those dates only:
select DUE_DATE, count(*)
from DATA
where DUE_DATE in (select distinct DUE_DATE
from DATA
order by DUE_DATE desc limit 6)
group by DUE_DATE
I hope I helped!
Are you looking for fetch first?
select DUE_DATE, count(*)
from DATA
group by DUE_DATE
order by DUE_DATE desc
fetch first 6 rows only;

Is there a better way to see if customers took a 'break period' in SQL?

I am trying to see how many customers have returned after two years of dormancy. I also have to join two tables with older (before 2008) and newer purchasing data (after 2008). Each table has the same columns but different records.
For example, if Bill made a purchase on July 1, 2010 and didn't purchase anything else until July 1, 2012, he would be counted. Each purchase date has its own column.
I've been suggested to try out the code shown below, but it is super slow (I have a lot of records). I was wondering if there is a more efficient way to do this.
(I am using Redshift)
FROM (SELECT s.cust_id, s.purchase_date,
LAG(s.purchase_date) OVER (PARTITION BY s.cust_id ORDER BY s.purchase_date,) as prev_pd
FROM newer_purchase_data s JOIN older_purchase_data l on s.cust_id = l.cust_id
) t
WHERE DATEDIFF(days, prev_pd, s.purchase_date) >= 730 /* 2 years in days */
;
currently you are causing a many to many join ( i think) - which causes your inefficiency.
Try this structure for your query
select *
FROM (SELECT cust_id, purchase_date::timestamp,
LAG(purchase_date::timestamp,1) OVER (PARTITION BY cust_id ORDER BY purchase_date) as prev_pd
FROM
(select cust_id,purchase_date from older_purchase_data
union all
select cust_id,purchase_date from newer_purchase_data
) as x
) t
WHERE DATEDIFF('day', prev_pd, purchase_date) >= 730 /* 2 years in days */