I have the following table
customerID | orderID | orderDate
----------------------------------
1 | 67 | 2015-12-15
1 | 66 | 2015-10-20
1 | 65 | 2015-1-7
2 | 64 | 2014-9-6
2 | 63 | 2014-7-8
3 | 62 | 2015-1-15
I need to identify all the customerIDs that have at least 3 distinct orderIDs within a 12 month period in 2014 and 2015
Hmmm. You could do something like this:
select distinct customerId
from t
where 3 <= (select count(*)
from t t2
where t2.customerId = t.customerId and
t2.date >= t.date and
t2.date < date_add(t.date, interval 12 month)
);
An index on (customerId, date) would help performance. And, you might need count(distinct OrderId) in the subquery, but that doesn't seem necessary given your sample data.
Try this:
SELECT customerID, order_count FROM (SELECT customerID, COUNT(DISTINCT orderID) AS
order_count WHERE YEAR(orderDate) = 2014 GROUP BY customerID) AS
table_orders WHERE order_count >= 3
You could change first WHERE clausule in order to change date range, i suggest you a approach counting in all 2014 year
Related
How do you display the latest data for a particular month?
For example I have data like this
date data
2003-04-18 | 12
2003-04-25 | 14
2003-05-16 | 51
2003-05-23 | 21
2003-05-30 | 22
2003-06-06 | 11
2003-06-27 | 14
I want to display data
date data
2003-04-25 | 14
2003-05-30 | 22
2003-06-27 | 14
What kind of example query is used?
i try this query, but showing all data
SELECT tgl_hargaemas, harga FROM tbl_hargaemas
WHERE tgl_hargaemas >= '2003-01-03' - INTERVAL DAYOFMONTH('2018-01-03') MONTH
Use a simple GROUP BY sub query to find the max date for each year-month followed by an INNER JOIN:
SELECT t.*
FROM (
SELECT MAX(date) AS maxdate
FROM t
GROUP BY YEAR(date), MONTH(date)
) AS g
INNER JOIN t ON g.maxdate = t.date
Demo on DB<>Fiddle
I have an SQL query I am using to pull data from an orders database. I am querying 2 tables and combining the results using UNION ALL. However, the UNION ALL does not seem to work as expected. Here is the query I am using:
SELECT year(oc_order.date_added) AS year, COUNT(oc_order.order_id) as cnt, SUM( ifnull(oc_order.new_total,oc_order.total) ) as total
FROM oc_order
WHERE oc_order.order_status_id IN (1,3,5)
AND MONTH(oc_order.date_added) BETWEEN '01' AND '02'
AND DAY(oc_order.date_added) BETWEEN '01' AND '31'
GROUP BY year(oc_order.date_added)
UNION ALL
SELECT ifnull(year(str_to_date(oc_return_custom.date_added,'%d-%m-%Y %H:%i:%s')),year(str_to_date(oc_return_custom.date_added,'%Y-%m-%d %H:%i:%s')) ) AS year, COUNT(oc_return_custom.return_id) as cnt, SUM( oc_return_custom.total ) as total
FROM oc_return_custom
WHERE ifnull(MONTH(str_to_date(oc_return_custom.date_added,'%d-%m-%Y %H:%i:%s')),MONTH(str_to_date(oc_return_custom.date_added,'%Y-%m-%d %H:%i:%s')) ) BETWEEN '01' AND '02'
AND ifnull(DAY(str_to_date(oc_return_custom.date_added,'%d-%m-%Y %H:%i:%s')),DAY(str_to_date(oc_return_custom.date_added,'%Y-%m-%d %H:%i:%s')) ) BETWEEN '01' AND '31'
GROUP BY ifnull(year(str_to_date(oc_return_custom.date_added,'%d-%m-%Y %H:%i:%s')),year(str_to_date(oc_return_custom.date_added,'%Y-%m-%d %H:%i:%s')) )
ORDER BY year DESC
This is what I get from the query:
+=======+========+=======+
| year | cnt | total |
+=======+========+=======+
| 2016 | 200 | 1000 |
| 2016 | 50 | 200 |
| 2015 | 100 | 800 |
| 2015 | 10 | 50 |
+=======+========+=======+
But this is what I wanted to get:
+=======+========+=======+
| year | cnt | total |
+=======+========+=======+
| 2016 | 250 | 1200 |
| 2015 | 110 | 850 |
+=======+========+=======+
Can someone tell me what I am doing wrong???
Notes:
The oc_order table's date_added column is datetime whereas oc_return_custom 's date_added column is just text.
UNION ALL simply puts together two data sets produced by separate GROUP BY operations.
To get the expected result set you have to wrap the query in a subquery and apply an additional GROUP BY:
SELECT year, SUM(cnt) AS cnt, SUM(total) AS total
FROM ( ... your query here ...) AS t
GROUP BY year
I have a table with :
user_id | order_date
---------+------------
12 | 2014-03-23
12 | 2014-01-24
14 | 2014-01-26
16 | 2014-01-23
15 | 2014-03-21
20 | 2013-10-23
13 | 2014-01-25
16 | 2014-03-23
13 | 2014-01-25
14 | 2014-03-22
A Active user is someone who has logged in last 12 months.
Need output as
Period | count of Active user
----------------------------
Oct-2013 - 1
Jan-2014 - 5
Mar-2014 - 10
The Jan 2014 value - includes Oct -2013 1 record and 4 non duplicate record for Jan 2014)
You can use a variable to calculate the running total of active users:
SELECT Period,
#total:=#total+cnt AS `Count of Active Users`
FROM (
SELECT CONCAT(MONTHNAME(order_date), '-', YEAR(order_date)) AS Period,
COUNT(DISTINCT user_id) AS cnt
FROM mytable
GROUP BY Period
ORDER BY YEAR(order_date), MONTH(order_date) ) t,
(SELECT #total:=0) AS var
The subquery returns the number of distinct active users per Month/Year. The outer query uses #total variable in order to calculate the running total of active users' count.
Fiddle Demo here
I've got two queries that do the thing. I am not sure which one's the fastest. Check them aginst your database:
SQL Fiddle
Query 1:
select per.yyyymm,
(select count(DISTINCT o.user_id) from orders o where o.order_date >=
(per.yyyymm - INTERVAL 1 YEAR) and o.order_date < per.yyyymm + INTERVAL 1 MONTH) as `count`
from
(select DISTINCT LAST_DAY(order_date) + INTERVAL 1 DAY - INTERVAL 1 MONTH as yyyymm
from orders) per
order by per.yyyymm
Results:
| yyyymm | count |
|---------------------------|-------|
| October, 01 2013 00:00:00 | 1 |
| January, 01 2014 00:00:00 | 5 |
| March, 01 2014 00:00:00 | 6 |
Query 2:
select DATE_FORMAT(order_date, '%Y-%m'),
(select count(DISTINCT o.user_id) from orders o where o.order_date >=
(LAST_DAY(o1.order_date) + INTERVAL 1 DAY - INTERVAL 13 MONTH) and
o.order_date <= LAST_DAY(o1.order_date)) as `count`
from orders o1
group by DATE_FORMAT(order_date, '%Y-%m')
Results:
| DATE_FORMAT(order_date, '%Y-%m') | count |
|----------------------------------|-------|
| 2013-10 | 1 |
| 2014-01 | 5 |
| 2014-03 | 6 |
The best thing I could do is this:
SELECT Date, COUNT(*) as ActiveUsers
FROM
(
SELECT DISTINCT userId, CONCAT(YEAR(order_date), "-", MONTH(order_date)) as Date
FROM `a`
ORDER BY Date
)
AS `b`
GROUP BY Date
The output is the following:
| Date | ActiveUsers |
|---------|-------------|
| 2013-10 | 1 |
| 2014-1 | 4 |
| 2014-3 | 4 |
Now, for every row you need to sum up the number of active users in previous rows.
For example, here is the code in C#.
int total = 0;
while (reader.Read())
{
total += (int)reader['ActiveUsers'];
Console.WriteLine("{0} - {1} active users", reader['Date'].ToString(), reader['ActiveUsers'].ToString());
}
By the way, for the March of 2014 the answer is 9 because one row is duplicated.
Try this, but thise doesn't handle the last part: The Jan 2014 value - includes Oct -2013
select TO_CHAR(order_dt,'MON-YYYY'), count(distinct User_ID ) cnt from [orders]
where User_ID in
(select User_ID from
(select a.User_ID from [orders] a,
(select a.User_ID,count (a.order_dt) from [orders] a
where a.order_dt > (select max(b.order_dt)-365 from [orders] b where a.User_ID=b.User_ID)
group by a.User_ID
having count(order_dt)>1) b
where a.User_ID=b.User_ID) a
)
group by TO_CHAR(order_dt,'MON-YYYY');
This is what I think you are looking for
SET #cnt = 0;
SELECT Period, #cnt := #cnt + total_active_users AS total_active_users
FROM (
SELECT DATE_FORMAT(order_date, '%b-%Y') AS Period , COUNT( id) AS total_active_users
FROM t
GROUP BY DATE_FORMAT(order_date, '%b-%Y')
ORDER BY order_date
) AS t
This is the output that I get
Period total_active_users
Oct-2013 1
Jan-2014 6
Mar-2014 10
You can also do COUNT(DISTINCT id) to get the unique Ids only
Here is a SQL Fiddle
I have a mysql table points like this
id | points | orderid | date
1 | 10 | 1234 | 2014-01-14
2 | 20 | 4321 | 2014-02-04
3 | 10 | 1234 | 2014-01-13
I want to get count of records for unique orderids
like if i want to fech total records for month of jan then result will be
1 not 2 because i need to fetch records for unique orderids
Use the DISTINCT modifier in the COUNT() function.
SELECT YEAR(date) AS y, MONTH(date) AS m, COUNT(DISTINCT orderid)
FROM yourTable
GROUP BY y, m
SELECT MONTHNAME(date_reg) M, YEAR(date_reg) Y, COUNT(MONTHNAME(date_reg)) T
FROM users
WHERE date_reg BETWEEN DATE_ADD(DATE_SUB(DATE_SUB(LAST_DAY(NOW()), INTERVAL
DAY(LAST_DAY(NOW())) DAY), INTERVAL 5 MONTH), INTERVAL 1 DAY) AND
DATE_SUB(LAST_DAY(NOW()), INTERVAL DAY(LAST_DAY(NOW())) DAY)
GROUP BY M
ORDER BY Y, M DESC;
You can use substr function of MySQL to cut down the complete date string into year and month and group the resulting string.
select substr(createdTime,1,7) as month,COUNT(1) from TABLENAME where {CONDITION} group by month order by 1;
I'm trying to generate a SQL query to extract an average montly powerusage (of a year) for an ID.
+----+------------+------------+
| id | powerusage | date |
+----+------------+------------+
| 1 | 750 | 2011-12-2 |
| 1 | 1000 | 2011-12-1 |
| 1 | 1500 | 2011-11-15 |
| 1 | 100 | 2011-11-13 |
| 1 | 50 | 2011-11-10 |
| 2 | 500 | 2011-11-15 |
| 2 | 200 | 2011-11-13 |
+----+------------+------------+
So if ID = 1 I want (avg november + avg december) / 2 = (1750/2 + 1650/3) / 2 = 712.5
select AVG(powerusage) as avgMontlyPowerUsage
from usagetable
where id = 1 and YEAR(date) = 2011
But this will give me 680.
How do I do a average on a group?
Many thanks for all the answers! But I see my question is incorrect. See updated question
Something like
select AVG(montlyPowerUsage) from (
SELECT MONTH(date) as mnth,sum(powerusage) as montlyPowerUsage
from usagetable
where id = 1 and YEAR(date) = 2011 group by MONTH(date)
) t1
For Edited question
select AVG(montlyPowerUsage) from (
SELECT MONTH(date) as mnth,AVG(powerusage) as montlyPowerUsage
from usagetable
where id = 1 and YEAR(date) = 2011 group by MONTH(date)
) t1
mysql> select avg(powerusage)
from
(select monthname(date), sum(powerusage) as powerusage
from usagetable
where id=1 and year(date)=2011
group by monthname(date)) as avg_usage;
+-----------------+
| avg(powerusage) |
+-----------------+
| 1700.0000 |
+-----------------+
select avg(total_powerusage)
from
(select monthname(date), sum(powerusage) as total_powerusage
from usagetable
where id=1 and year(date)=2011
group by monthname(date)
) as avg_usage;
/* the use of subquery
is to return total of unique occurrences,
and sum powerusage of each occurrence,
which mean, you just need to apply AVG into the subquery */
This should give you monthly averages for every year and user. Some of the syntax may be MS SQL specific, but the logic should be good.
SELECT id, AVG(usage), year FROM
(SELECT id, SUM(powerusage) as usage, YEAR(date) as Year, MONTH(date) as Month
FROM usagetable
GROUP BY id, YEAR(date), MONTH(date)) as InnerTable
GROUP BY id, year
Try adding a group by on the id
GROUP BY id
Or the date, whichever suits.
SELECT SUM(powerusage) / (MONTH(MAX(`date`)) - MONTH(MIN(`date`)) + 1)
AS avgMontlyPowerUsage
FROM usagetable
WHERE id = 1
AND YEAR(`date`) = 2011
or (depending on what you need when data is sparse):
SELECT SUM(powerusage) / COUNT( DISTINCT MONTH(`date`) )
AS avgMontlyPowerUsage
FROM usagetable
WHERE id = 1
AND YEAR(`date`) = 2011
Warning: Neither of the above is optimized for performance.