SQL query to find the repetitions of data - mysql

I've a sample data
id date user_id customer_id status
1 2022-06-23 1 12 no response
2 2022-06-23 1 12 no response
3 2022-06-24 1 12 no response
4 2022-06-23 2 15 no response
4 2022-06-23 2 15 successful
5 2022-06-23 3 16 call later
I need to fetch those kind of records where a user_id called the same customer_id on the same day got only no response status more than once but not any other statuses.
The result for the above example would be
id
1
2

You can use aggregation and the conditions in the HAVING clause:
SELECT user_id, customer_id, date
FROM tablename
GROUP BY user_id, customer_id, date
HAVING COUNT(*) > 1 AND SUM(status <> 'no response') = 0
If you want the respective rows of the table use the above query with the operator IN:
SELECT *
FROM tablename
WHERE (user_id, customer_id, date) IN (
SELECT user_id, customer_id, date
FROM tablename
GROUP BY user_id, customer_id, date
HAVING COUNT(*) > 1 AND SUM(status <> 'no response') = 0
);
See the demo.

Related

SQL show all rows that have certain columns duplicated in a given time period

I have one table containing the following data: ID, name, barcode, status, time_created
I need to check if the same barcode exists multiple times in a given time period (e.g. one week) and if the last status has changed from 0 to 1.
Question: How can I get the correct results according to given timestamps?
With the following query I can list the duplicated lines:
SELECT id, name, barcode, status, time_created
FROM table_name WHERE barcode
IN (SELECT barcode
FROM table_name
GROUP BY
barcode HAVING COUNT(*)>1);
Results are:
id
name
barcode
status
time_created
34
testname
123456789
1
2022-06-22 11:25:17
36
testname2
123456789
1
2022-06-22 03:58:35
37
testname3
test
0
2022-06-22 03:57:46
40
testname3
test
1
2022-07-04 10:48:25
41
testname
123456789
1
2022-07-04 11:19:20
42
testname
123456789
0
2022-07-02 12:26:39
43
testname
123456789
0
2022-02-09 03:03:40
If I add time interval to the query it still displays results from BEFORE the given interval:
SELECT id, name, barcode, status, time_created
FROM table_name WHERE barcode
IN (SELECT barcode
FROM table_name
WHERE (time_created BETWEEN '2022-07-02 00:00:00' AND '2022-07-04 23:59:59')
GROUP BY
barcode HAVING COUNT(*)>1);
id
name
barcode
status
time_created
34
testname
123456789
1
2022-06-22 11:25:17
40
testname3
test
1
2022-07-04 10:48:25
41
testname
123456789
1
2022-07-04 11:19:20
42
testname
123456789
0
2022-07-02 12:26:39
43
testname
123456789
0
2022-02-09 03:03:40
Is there an error in my logic or the query?
So, to get desired results you need to
Get all duplicate barcode values ​​in given interval as you do
Get previous status and row number for each duplicate barcode ordered
by time_created. This will give you the ability to get the latest
values ​​in time and find out the current and previous status values.
Get the rows with the current status equal to 1 and the previous value equal to 0 and the maximum row number
Final query would be like this
WITH cte AS (
SELECT
table_name.*,
LAG(table_name.status) OVER (PARTITION BY table_name.barcode ORDER BY time_created) AS prev_status,
ROW_NUMBER() OVER (PARTITION BY table_name.barcode ORDER BY time_created) AS rn
FROM table_name
JOIN (
SELECT barcode
FROM table_name
WHERE time_created BETWEEN '2022-07-02 00:00:00' AND '2022-07-04 23:59:59'
GROUP BY barcode
HAVING COUNT(*) > 1
) t ON table_name.barcode = t.barcode
)
SELECT id, name, barcode, status, time_created
FROM cte t
WHERE status = 1
AND prev_status = 0
AND rn = (
SELECT MAX(rn)
FROM cte
WHERE barcode = t.barcode
)
Demo

mysql select record that matches 1 condition or another

I have this sample data:
id vendor date status
4 2 2020-04-15 2
266 2 2020-04-20 2
886 2 2020-05-07 2
5 3 2020-04-15 1
6 3 2020-04-15 0
8 3 2020-04-15 2
I am trying to select the record for each vendor where the either the status is 0 (taking priority over the next condition) or if that condition is not met, the latest record by date for each vendor.
Sample SQL:
select id, case
when status != 0 then id
else id
end
from
(select id, vendor, date, status
from sent
where vendor in (2,3)
group by id, vendor, date, status
order by vendor) as inner_table
group by vendor, id;
One way to do this is to UNION all records that have status = 0 with all records that have MAX(date) for a given vendor, but excluding max date records for those vendors that have a record with a status of 0:
SELECT *
FROM sent
WHERE status = 0
UNION ALL
SELECT sent.*
FROM sent
JOIN (
SELECT vendor, MAX(date) AS max_date
FROM sent
GROUP BY vendor
) d ON d.vendor = sent.vendor
AND d.max_date = sent.date
WHERE NOT EXISTS (
SELECT *
FROM sent s2
WHERE s2.vendor = d.vendor
AND s2.status = 0
)
ORDER BY vendor
Output (for your sample data):
id vendor date status
886 2 2020-05-07 2
6 3 2020-04-15 0
Demo on dbfiddle

MySQL: Count two date columns and group by day

I need to draw a line chart that will visualize both the orders and pickups for each day between certain dates. The order and pickup dates are stored in unixtime. My table looks something like this:
id order_date pickup_date
-------------------------------
1 1472749664 1472133376
2 1472551372 1472567548
3 1472652545 1472901368
4 1473154659 1473512323
5 1473512923 1475229824
6 1475586643 1475652635
What I am after is something like this
date orders pickups
-------------------------------
01-09-2016 1 0
02-09-2016 4 1
03-09-2016 3 2
04-09-2016 7 1
05-09-2016 0 0
06-09-2016 1 1
07-09-2016 6 3
08-09-2016 0 0
08-09-2016 3 5
10-09-2016 2 4
I know I can count based on one column, for example:
SELECT
COUNT(id) AS orders,
FROM_UNIXTIME(order_dates, '%d-%m-%Y') AS date
FROM orders
GROUP BY request_date
But I not sure how to count two columns and group them for each day.
You could use a query like this:
SELECT sum(orders) as orders, sum(pickups) as pickups, date
FROM (
SELECT
COUNT(id) AS orders, 0 as pickups,
FROM_UNIXTIME(`order_date`, '%d-%m-%Y') AS date
FROM orders
GROUP BY order_date
UNION
SELECT
0 AS orders, COUNT(id) as pickups,
FROM_UNIXTIME(`pickup_date`, '%d-%m-%Y') AS date
FROM orders
GROUP BY pickup_date ) ut
GROUP BY date
Here is a fiddle.

Query with multiple subqueries required in Mysql

I am looking for some query help
here is the following table data
Name Runs Status
Ram 50 out
Ram 103 not out
Krish 51 out
Sam 15 out
Ram 15 out
Krish 78 not out
I am expecting a single query to give the folllowing results
Name Total >100 >50&<100 TotalTimes Notout
Ram 168 1 1 3 1
Sam 15 0 0 1 0
Krish 129 0 2 2 1
I am able to write the query to get the total, Totaltimes with the help of Group By functionalities, I am stuck with the rest
Here is the query I have come up
select Name, sum(Runs) as total, count(*) as totalTimes
from tempTable
where classID IN (Select classID from upcoming_Clases where classes_id=175)
group by Name order by total desc
I am using the Mysql Database
You can do this using case:
select Name,
sum(Runs) as total,
count(case when Runs>100 then 1 end) `>100`,
count(case when Runs>50 and Runs<100 then 1 end) `>50&<100`,
count(*) as totalTimes,
count(case when Status='not out' then 1 end) `Not Out`
from tempTable
where classID IN (Select classID from upcoming_Clases where classes_id=175)
group by Name order by total desc
You can use SUM() together with IF() to test your criteria:
SELECT
Name,
SUM(Runs) AS Total,
SUM(IF(Runs>100, 1, 0)) AS `>100`,
SUM(IF(Runs>50 AND Runs<100), 1, 0) AS `>50&<100`,
COUNT(*) AS TotalTimes,
SUM(IF(Status='not out', 1, 0)) AS Notout
FROM tempTable
WHERE classID IN (SELECT classID FROM upcoming_Clases WHERE classes_id = 175)
GROUP BY Name
ORDER BY Total DESC

MYSQL select maximum sum of purchases

I have the following Table named Order
Orders Table
___________________________________________________
orderiD | userId | OrderType | Order_Date | Amount
________|________|___________|____________|________
1 1 0 12/12/2009 1
2 1 1 13/12/2009 2
3 1 1 14/12/2009 3
4 2 0 12/12/2009 4
5 2 1 16/12/2009 2
6 1 0 14/12/2009 5
7 2 1 17/12/2009 4
8 2 0 10/12/2010 2
___________________________________________________
I need to create query which returns user id with maximum SUM of purchases.
I tried the following
Select MAX(GRP.sumAmmount), o.userId join
(Select SUM(o.Amount) as sum_ammount, o.userId as UID from Orders GROUP BY(o.userID)) as GRP on o.userId=GRP.UID GROUP BY(GRP.UID)
But I believe I'm missing something.
Can you help?
If I understand your question correctly, you want to return the UserID which has the maximum SUM (total) of purchases. So the above records will result:
UserID Total Amount
2 12
And the simpliest solution would be:
SELECT UserID, SUM(AMOUNT) as TotalAmount
FROM Orders
GROUP BY UserID
ORDER BY TotalAmount DESC
LIMIT 1
I'm ready to edit this if I'm wrong. :-) (PS: Please add your desired result)
Thanks.
UPDATE 1
Derived from you query:
Select MAX(SUM(o.Amount)) as sum_ammount,
o.userId as UID
FROM Orders o
GROUP BY o.userID
ORDER BY sum_ammount DESC
LIMIT 1
See below, its working.
SELECT userId, sum(Amount) as 'Total'
FROM Orders
GROUP BY userId
ORDER BY Total DESC
LIMIT 1
Output is
+++++++++++++++
userId + Total
+++++++++++++++
2 + 12
+++++++++++++++
I also tried after adding new row as
insert into Orders values (9,1,0,'2010-12-10 12:12:12',10)
Output is
+++++++++++++++
userId + Total
+++++++++++++++
1 + 21
+++++++++++++++
I prefer to have this solution
SELECT UserID, SUM(AMOUNT) as TotalAmount
FROM Orders
GROUP BY UserID
having SUM(AMOUNT) = (select sum(amount) as col1
from orders
group by userid
order by col1 desc
limit 1
)
This sql will show all users who have max purchases
Just try to change amount of orderid 1 to be 2 , then this sql will show both.