Unique & Rept Customer Sales based on date - mysql

I am new to Mysql, I have the data like this,
Order_dt User_ID Sales
28-03-2022 PRPK-12 84
28-03-2022 PRPK-11 41
28-03-2022 PRPK-10 55
28-03-2022 PRPK-12 76
26-03-2022 PRPK-10 54
27-03-2022 PRPK-11 88
27-03-2022 PRPK-11 51
27-03-2022 PRPK-10 40
27-03-2022 PRPK-10 40
& I need o/p like below the format.
Order_date Unique_Cx Unique_Cx_Sales Rept_Cx Rept_Cx_Sales
26-03-2022 1 54 0 0
27-03-2022 0 0 2 219
28-03-2022 2 96 1 160
I'm getting only unique & Rept count by using the 'Having' function, but im unable to map with the sales. Kindly help.
Thanking you.

First group by dt and user id in sub query then use conditional aggregation
select order_dt,
sum(case when cd = 1 then 1 else 0 end) unique_cx,
sum(case when cd = 1 then sales else 0 end) unique_cx_sales,
sum(case when cd > 1 then 1 else 0 end) repeat_cx,
sum(case when cd > 1 then sales else 0 end) repeat_cx_sales
from
(
select order_dt, user_id,
count(*) cd,sum(sales) sales
from t
group by order_dt,user_id
) s
group by order_dt
;

Related

MYSQL get multiple fields count using Group by multiple fields by date

I want count by using group two columns. I have data like this:
id sectionid date
1 1 2015-09-16
2 1 2015-09-16
3 2 2015-09-16
4 2 2015-09-16
5 3 2015-09-16
6 1 2015-09-17
7 2 2015-09-18
8 2 2015-09-18
Result will be:
Date section1count section2count section3count
2015-09-16 2 2 1
2015-09-17 1 0 0
2015-09-18 0 2 0
Thanks in advance.
You can use a combination of the SUM() function along with GROUP BY to get the result set you want:
SELECT date AS Date,
SUM(CASE WHEN sectionid=1 THEN 1 ELSE 0 END) AS section1count,
SUM(CASE WHEN sectionid=2 THEN 1 ELSE 0 END) AS section2count,
SUM(CASE WHEN sectionid=3 THEN 1 ELSE 0 END) AS section3count
FROM table
GROUP BY date
SQLFiddle
her is my result. You can compare it to count each section
SELECT
SUM(IF( m.sectionid = 1 , 1,0)) section1count,
SUM(IF( m.sectionid = 2 , 1,0)) section2count,
SUM(IF( m.sectionid = 3 , 1,0)) section3count,
m.date
FROM myt m
GROUP BY m.`date`;

Use IF in mysql select query to change the WHERE clause

I need to create a select statement on a table like this:
id rank name city
34 0 adm TO
44 0 sas BA
44 1 wqe BS
92 0 adm TO
92 1 ter BO
92 2 ter BO
92 3 ter RM
what I want to select is to count the number of rows where rank is > 0 but only for ids that have more than one rank value. For those id that just have one record, thus rank is 0, then I want to pick that record. If I use:
SELECT id, count(rank) as t
FROM mytable
WHERE rank > 0
GROUP BY id
then, for instance, I omit id=34.
My optimal results set would be:
id t
34 1
44 1
92 3
Any hint on how to accomplish this task?
You can use something like the following:
SELECT id,
CASE
WHEN cntNonZero = 0 THEN cntZero
ELSE cntNonZero
END AS t
FROM (
SELECT id,
COUNT(CASE WHEN rank > 0 THEN 1 END) AS cntNonZero,
COUNT(CASE WHEN rank = 0 THEN 1 END) AS cntZero
FROM mytable
GROUP BY id ) s
Demo here

How to build this query?

i have table
http://oi58.tinypic.com/2s7xreo.jpg
id action_date type item_id quantity
--- ----------- ---- ------- --------
87 4/25/2014 1 s-1 100
88 4/1/2014 1 s-1 150
89 4/4/2014 1 s-1 200
90 4/3/2014 1 s-2 222
91 4/7/2014 1 s-2 10
96 4/4/2014 1 s-2 8
97 4/22/2014 1 s-2 8
98 4/21/2014 2 s-1 255
99 4/5/2014 2 s-1 6
100 4/6/2014 2 s-2 190
101 4/6/2014 2 s-3 96
102 4/8/2014 2 s-1 120
103 4/15/2014 2 s-2 3
104 4/16/2014 2 s-2 3
type column which mean if 1 this is in item to my shop >>> if 2 this is out item from my shop >>
i need query to give me result like this
item in out net
s1 300 195 105
and so on >>
how to write query that give me this result >>
and if i must but them in tow table >> table for the in and table for the out if that help >>> how it build the query >
and thanx in advance :)
note :: i am work on access
One way to get the result is to use an aggregate function on an expression that conditionally returns the value of quantity, based on the value of type.
SELECT t.item
, SUM(CASE WHEN t.type = 1 THEN t.quantity ELSE 0 END) AS in_
, SUM(CASE WHEN t.type = 2 THEN t.quantity ELSE 0 END) AS out_
, SUM(CASE WHEN t.type = 1 THEN t.quantity ELSE 0 END)
- SUM(CASE WHEN t.type = 2 THEN t.quantity ELSE 0 END) AS net_
FROM mytable t
GROUP BY t.item
This approach works in Oracle, as well as MySQL and SQL Server.
(If you remove the SUM() aggregate function and the GROUP BY clause, you can see how that CASE expression is working. The query above gives the result you specified, this one is just a demonstration that helps "explain" how that query works.)
SELECT t.item
, CASE WHEN t.type = 1 THEN t.quantity ELSE 0 END AS in_
, CASE WHEN t.type = 2 THEN t.quantity ELSE 0 END AS out_
, t.*
FROM mytable t
UPDATE
Unfortunately, Microsoft Access doesn't support CASE expressions. But Access does have an iif function. The same approach should work, the syntax might be something like this:
SELECT t.item
, SUM(iif(t.type = 1, t.quantity, 0) AS in_
, SUM(iif(t.type = 2, t.quantity, 0) AS out_
, SUM(iif(t.type = 1, t.quantity, 0)
- SUM(iif(t.type = 2, t.quantity, 0) AS net_
FROM mytable t
GROUP BY t.item
SELECT item_id,
In_col,
Out_col,
(In_col - Out_col) AS Net
FROM
(SELECT item_id,
sum(CASE WHEN TYPE = 1 THEN quantity END) AS In_col,
sum(CASE WHEN TYPE = 2 THEN quantity END) AS Out_col
FROM TABLE
GROUP BY item_id) AS t1;
I hope this what you need.

generate multiple sums from the same query

I have a table like this:
id person_id total amount date_time
1 101 2000 2001-12-10
2 102 1000 2001-12-10
3 102 3000 2001-12-10
4 102 2000 2001-12-10
5 103 1000 2001-12-11
6 101 1000 2001-12-11
7 102 3000 2001-12-11
8 102 4000 2001-12-11
9 102 4000 2001-12-11
I want the output to be like the one below for the date 2001-12-11
person_101 person_102 person_103
1000 11000 1000
I've tried using the SUM() function but am stuck with the WHERE and JOIN clauses.
How do I solve this?
SELECT
SUM(CASE WHEN person_id = 101 THEN total_amount ELSE 0 END) as person_101,
SUM(CASE WHEN person_id = 102 THEN total_amount ELSE 0 END) as person_102,
SUM(CASE WHEN person_id = 103 THEN total_amount ELSE 0 END) as person_103
FROM
my_table
WHERE
date_time ='2001-12-11'
You need to pivot the data, unfortunately this is not dynamic in mysql, try this:
SELECT
SUM(IF(person_id = 101,total_amount,0)) as person_101,
SUM(IF(person_id = 102,total_amount,0)) as person_102,
SUM(IF(person_id = 103,total_amount,0)) as person_103
FROM
my_table
WHERE
date_time = '2001-12-11'
Also you can do this pivot split by date , you just need to have it in the field list and group by it :
SELECT
date_time,
SUM(IF(person_id = 101,total_amount,0)) as person_101,
SUM(IF(person_id = 102,total_amount,0)) as person_102,
SUM(IF(person_id = 103,total_amount,0)) as person_103
FROM
my_table
GROUP BY
date_time

MySQL grouping totals by multiple date and results using case

I have a results table which lists a set of values, each linking to another table containing the date that result was made.
I have working SQL to get all the dates (using CASE's) however I can only retrieve a single range of results.
Select
count(CASE
WHEN results.test_id IN ( SELECT id
FROM `test`
WHERE `posted`
BETWEEN '2011-07-01 00:00:00'
AND '2011-07-01 23:59:59')
THEN results.test_id
ELSE NULL
END) AS "1st July"
from `results`
WHERE results.window_id = 2 and results.mark > 90;
I also have another SQL query which gets all the ranges but can only work for one date at a time.
SELECT
CASE
when mark > 90 then '>90%'
when mark > 80 then '>80%'
when mark > 70 then '>70%'
END as mark_results,
COUNT(*) AS count
FROM (SELECT mark from results where window_id =2) as derived
GROUP BY mark_results
ORDER BY mark_results;
What I'd like is to have everything in one unified query, displaying the relevant totals for each range of results. such as below:
Result Range | 1st July | 2nd July | 3rd July | 4th July
>90% | 0 | 0 | 0 | 1
>80% | 1 | 2 | 1 | 1
>70% | 4 | 5 | 5 | 4
So that the totals for each range are displayed under their date.
I assume it's possible.
The following statement joins results and tests in the FROM clause. It then aggregates the query by the mark range, with the counts per day:
Select (CASE when mark > 90 then '>90%'
when mark > 80 then '>80%'
when mark > 70 then '>70%'
END) as mark_results,
sum(case when posted BETWEEN '2011-07-01 00:00:00' AND '2011-07-01 23:59:59' then 1 else 0 end) as July01,
sum(case when posted BETWEEN '2011-07-02 00:00:00' AND '2011-07-02 23:59:59' then 1 else 0 end) as July02,
. . .
from `results` r join
test t
on r.test_id = t.test_id
WHERE r.window_id = 2 and results.mark > 90
group by (CASE when mark > 90 then '>90%'
when mark > 80 then '>80%'
when mark > 70 then '>70%'
END)
order by 1
Just add whatever days you want to the SELECT clause.
I should add . . . if you want all the dates, you need to put them on separate rows:
Select date(posted) as PostedDate,
(CASE when mark > 90 then '>90%'
when mark > 80 then '>80%'
when mark > 70 then '>70%'
END) as mark_results,
count(*) as cnt
. . .
from `results` r join
test t
on r.test_id = t.test_id
WHERE r.window_id = 2 and results.mark > 90
group by date(posted),
(CASE when mark > 90 then '>90%'
when mark > 80 then '>80%'
when mark > 70 then '>70%'
END)
order by 1, 2
In fact, you might consider having a separate row for each date, with the ranges pivoted as columns.