related to query using SQL - mysql

In oracle sql, how to get the count of newly added customers only for the month of april and may and make sure they werent there in the previous months
SELECT CUSTOMER ID , COUNT(*)
FROM TABLE
WHERE DATE BETWEEN '1-APR-2018' AND '31-MAY-2018' AND ...
If we give max (date) and min(date), we can compare the greater date to check if this customer is new , correct?
expected output is month count
april ---
may ---
should show the exact count how many new customers joined in these two months

One approach is to use aggregation:
select customer_id, min(date) as min_date
from t
group by customer_id
having min(date) >= date '2018-04-01 and
min(date) < date '2018-06-01';
This gets the list of customers (which your query seems to be doing). To get the count, just use count(*) and make this a subquery.

Related

SQL Query using 5 aggregate functions

How do I query the following:
For each customer, product and month, count the number of sales transactions that were between the previous and the following month's average sales quantities. For January and December, display NULL or 0.
Can only use: 5 aggregate functions (sum, count, avg, max & min)
This is the table reference:
create table sales
(
cust varchar(20),
prod varchar(20),
day integer,
month integer,
year integer,
state char(2),
quant integer,
date date
);
Schema:
Example of my Desired Result
I am stuck with the following codes. I'm having a hard time how to execute it.
SELECT cust, prod, month, COUNT(*) AS SALES_COUNT_BETWEEN_AVGS
FROM sales
I use MySQL. Please guide me thank you.
Maybe try a query like below
the first part is to calculate averages using group by
second part is to use to those averages in a JOIN twice for past month and future month
third part is WHERE clause in which we compare data. Note we have used greatest and least functions to determine min and max between two values from past and next month
Query
WITH T AS
(SELECT cust, prod, month, AVG(quant) AS avg_quantity
FROM sales
group by cust, prod, month
)
SELECT S.cust, S.prod, S.month, COUNT(1) AS Sales_count
FROM sales S
LEFT JOIN T T1
ON T1.cust=S.Cust AND
T1.prod=S.Prod AND
T1.Month=S.Month-1
LEFT JOIN T T2
ON T2.cust=S.Cust AND
T2.prod=S.Prod AND
T2.Month=S.Month+1
WHERE S.quant BETWEEN IFNULL(LEAST(T1.avg_quantity,T2.avg_quantity),0) AND IFNULL(GREATEST(T1.avg_quantity,T2.avg_quantity),0)

Subquery returns more than 1 row, how can I solve?

Question: Show the category of competitions that have always been hosted in the same country during May 2010. What is wrong with my query?
select Category
from competition
where Date >= '2010-01-01' and Date <= '2010-12-31'
group by Country, Category
having count(*) = (select count(*)
from competition
where Date >= '2010-01-01' and Date <= '2010-12-31'
group by Category)
You don't need two queries. Just use one query that checks that the count of countries is 1.
select category, count(DISTINCT country) AS country_count
from competition
where Date BETWEEN '2010-05-01' and '2010-05-31'
group by Category
HAVING country_count = 1
I also corrected the dates to be just May, not the whole year 2010.
Remove the GROUP BY if you that is making you return more than 1 row (in your HAVING CLAUSE. If you give me an example dataset and what you want I can help you more
I'd try something like this to start with:
SELECT COUNTRY
, CATEGORY
, COUNT(COUNTRY)
FROM COMPETITION
WHERE DATE BETWEEN '2010-04-30' AND '2010-06-01'
ORDER BY CATEGORY DESC, COUNT(COUNTRY) DESC
;
Your original query's date limits are just for the year of 2010 but you specified you only wanted May 2010. If the Date column is a date or datetime time you'll need to cast the string to the appropriate datatype.
Your question asked "always hosted by one country" - do you know that a competition is only going to be hosted by one country during that particular month? If you do, you're pretty much done. If you don't, however, then you need to clarify what your criteria really are

How can I extract customers who have transacted since a specific date? (active customers definition)

All,
My definition of an active client is anyone who has transacted since November 2019. I am unsure how i can do this. e.g.
select
customerid,
sum(count) as transaction_count,
sum(value) as dollar_amount
from
cust_orders
my table above is at transaction level e.g. transaction_id = 1, 2... etc..I roll it up at customer level but i only want customers who have transacted at least once since November 2019. I don't think it is as simple as adding: 'where yearmonth > 201911'. since e.g. if I have one customer who hasn't transacted since then i don't want any of their aggregated stats above. And if i have had customers who have transacted since november 2019, i do want their transaction counts prior to this included. perhaps i could do:
select
customerid,
sum(count) as transaction_count,
sum(value) as dollar_amount
from
cust_orders where customerid in (select
distinct
customerid
from cust_orders where yearmonth > 201911))
)
does this make sense?
First, you need aggregation in your first query. Second, you can use a HAVING clause to identify the active customers:
select customerid,
sum(count) as transaction_count,
sum(value) as dollar_amount
from cust_orders
group by customerid
having max(yearmonth) >= 201911;
Note: I interpret "since Nov 2011" as including that month, so I changed the comparison to >=.

I need the way to aggregate based on column value using MySQL

I am learning Charts in Laravel, i need to draw Line graph for daily Student Attendance for those students come late or on time. I tried to write MYSQL query but it doesn't work
I tried subquery on same table to get data for daily students and i also need 7 dates only not full date, like date is stored in db as 09/08/2019 but i need it as 08 as date.
SELECT Date, COUNT(*) AS TimeStudent
FROM attendance WHERE `Attendance`='OnTime' AND (SELECT COUNT(*) AS
LateStudent FROM attendance
WHERE `Attendance`='Late'
GROUP BY `Date`
ORDER BY LateStudent DESC)
GROUP BY `Date`
ORDER BY TimeStudent DESC
but i got
[Err] 1241 - Operand should contain 1 column(s)
, because i can't use to fetch Date again in subquery while use it after where clause. Any one help me plz.
Here is a way to aggregate based on column value.
This query will give you count of on time and late student for a particular date.
SELECT
`Date`,
DATE_FORMAT(`Date`, '%d') AS Month_Date, -- You can modify it as per your requirement
SUM(IF(`Attendance` = 'OnTime', 1, 0)) AS OnTime_Count,
SUM(IF(`Attendance` = 'Late', 1, 0)) AS Late_Count
FROM attendance
WHERE `Date` >= CURRENT_DATE - INTERVAL 7 DAY
GROUP BY `Date`;

Moving average in SQL

I have a MySQL database populated with power consumption over 20 years.
I want to query the average of the power consumption over every month, from a given month.
For example with this database,
date power_consumption
2014/03/30 30
2014/04/30 40
2014/05/30 50
2014/06/30 20
The result would be, from 2014/04
month average_so_far_from_april_2014
2014/04 40.0
2014/05 45.0
2014/06 36.667
If I cannot achieve this in one query, what query should I go for to retrieve the most useful data for this task? (My naive approach is to query the whole table out and calculate the average in my application.)
Join the table of sub query against the consumption table which gets the unique months against the table of consumption, with a join condition that the year / month is less than or equal to the one from the sub query and use the AVG aggregate function on the power consumption from the table grouped by the year / month
Something like this:-
SELECT consumption_month,
AVG(b.power_consumption)
FROM
(
SELECT DISTINCT DATE_FORMAT(`date`, '%Y%m') AS consumption_month FROM consumption_table a
) a
INNER JOIN consumption_table b
ON consumption_month >= DATE_FORMAT(b.`date`, '%Y%m')
WHERE b.`date` >= '2014/04/01'
GROUP BY consumption_month
SQL fiddle:-
http://www.sqlfiddle.com/#!2/16588/2
If you only had one record per month you could simplify it more by just doing a join of the table against itself without the need for the sub query.
GROUP BY is for this kind of problems. The average is calculated for each distinct value of the expression the the GROUP BY clause.
SELECT DATE_FORMAT(date, '%Y/%m'), AVG(power_consumption)
FROM table_name
WHERE date > ...
GROUP BY DATE_FORMAT(date, '%y/%m')
ORDER BY DATE_FORMAT(date, '%y/%m')
You get the average for each month, DATE_FORMAT(date, '%y/%m') is year and month in format YYYY/MM