how to select Count of date ranges from mysql table - mysql

I have a table:
Name Registered Date
Amit 2017-01-01
Akshay 2017-01-03
Ankith 2017-01-05
Amit 2017-01-12
Amit 2017-01-13
Amit 2017-02-01
Amit 2017-02-01
I want to write a query which will display the registration weekly report:
Say date between 2017-01-01 to 2017-03-01
Week Count
2017-01-01 3
2017-01-08 2
2017-01-15 0
2017-01-22 0
2017-01-29 2
2017-02-05 0
2017-02-12 0
2017-02-19 0
2017-02-26 0
Here Count is the number of people who registered that week. 3 people registered in between 2017-01-01 to 2017-01-07.
So which query i have to use for this result?
Thanks

If you can use the WEEK function and display the week number instead of a date, then:
select dummy.n, count(table.RegiseredDate)
from (SELECT 1 as n UNION SELECT 2 as n UNION SELECT 3 as n ... UNION SELECT 53 as n) dummy
left outer join table on dummy.n=WEEK(table.Registered Date)
where start_date>= x and end_date<= y
group by WEEK(Registered Date)

Related

how do i get the correct id with the query results

I want to create a stored procedure in MySQL, but first, I want to get the query right. However, I keep getting the problem that I can't seem to get the correct id back from my query that correspond with the DateTime stamps that I get back.
this is the table I am trying to get the result from:
id EventId start end
1 1 2019-04-05 00:00:00 2019-04-07 00:00:00
2 2 2020-04-03 00:00:00 2020-04-03 00:00:00
3 3 2020-04-02 00:00:00 2020-04-02 00:00:00
7 1 2020-06-11 00:00:00 2020-06-11 00:00:00
9 2 2020-06-18 00:00:00 2020-06-18 00:00:00
10 3 2020-06-11 00:00:00 2020-06-11 00:00:00
11 3 2020-06-07 00:00:00 2020-06-07 00:00:00
query:
SELECT DISTINCT Eventid, MIN(start), id
from date_planning
WHERE `start` >= NOW()
GROUP BY Eventid
this gives me the following result
EventId Min(start) id
1 2020-06-11 00:00:00 3
2 2020-06-18 00:00:00 9
3 2020-06-07 00:00:00 10
but these are the correct ids that belong to those DateTimes:
EventId Min(start) id
1 2020-06-11 00:00:00 7
2 2020-06-18 00:00:00 9
3 2020-06-07 00:00:00 11
You want the row with the minimum "future" date for each eventId. To solve this greatest-n-per-group problem, you need to filter rather than aggregate. Here is one option using a correlated subquery:
select dt.*
from date_planning dt
where dt.start = (
select min(dt1.start)
from date_planning dt1
where dt1.eventId = dt.eventId and dt1.start >= now()
)
For performance, you need an index on (eventId, start).

SQL joining on two columns with a variation on the first column

I have two tables:
Table 1: planA
ID Date Count
3 2017-01-01 10
2 2017-02-03 15
10 2017-01-30 8
Table 2: planB
ID Date Value
3 2017-01-02 11
2 2017-02-04 12
21 2017-01-30 3
3 2017-02-03 33
What I want to do is to join the two tables on (ID and Date) columns.
However, on Date, I want to use the next day to the date on the table 1.
Therefore, the joined table should look like the following:
PlanA.ID PlanA.Date PlanB.Date PlanA.Count PlanB.Value
3 2017-01-01 2017-01-02 10 11
2 2017-02-03 2017-02-04 15 12
Is this even possible?
Any suggestion would be appreciated!
Yes it is possible:
select
PlanA.ID,
PlanA.Date,
PlanB.Date,
PlanA.Count,
PlanB.Value
from
PlanA inner join PlanB
on (
PlanA.ID = PlanB.ID
and
PlanA.Date + INTERVAL 1 DAY = PlanB.Date
)
if Date is a column of type date, + INTERVAL 1 DAY will return the next day of the one given, and then you can perform the join.

How to get the count and the sum of a value in a column at the same time

Now I have a table like the one below:
Year | Month | Day | Hour | Value
2014 1 1 0 111
2014 1 1 1 222
2014 1 1 2 333
2014 1 1 4 444
(no 3:00am on 2014-1-1)
... ... ... ... ...
2014 1 2 0 555
2014 1 2 1 666
2014 1 2 2 777
2014 1 2 3 888
... ... ... ... ...
How can I get a list of the average of the values associated with a specific Hour value?
SELECT AVG(Value), Hour
FROM tableA
GROUP BY Hour
Hmm, you know there is an AVG() function right?
SELECT hour, AVG(value) avg_value
FROM table1
GROUP BY hour
If you want the missing hours to count as zero you'll have to do something a bit more fancy. Adding the zeros would probably be a lot easier however.

SQL query to show zero instead of not shown record

I have these two tables:
Reception
id reception_date tin_lot company_id client_id quantity weight
1 2013-12-03 00:00:00 1 1 1 10 1980.00
2 2013-12-03 00:00:00 2 1 1 1 150.00
3 2013-12-13 00:00:00 3 1 2 10 4500.00
4 2013-12-13 00:00:00 4 2 5 5 2300.00
Payment
id payment_date amount reception_id
1 2013-12-03 00:00:00 500.0 1
2 2013-12-03 00:00:00 1200.0 3
The result I want to obtain is the following:
Expected result
id reception_date tin_lot client_id weight payment_made
1 2013-12-03 00:00:00 1 1 1980.00 500.0
2 2013-12-03 00:00:00 2 1 150.00 0.0
3 2013-12-13 00:00:00 3 2 4500.00 1200.0
4 2013-12-13 00:00:00 4 5 2300.00 0.0
I'm trying this query:
select rec.id
rec.reception_date,
rec.tin_lot,
rec.client_id,
rec.weight,
pay.payment_made
from liquidation.reception rec, liquidation.payment pay
where pay.recepcion_id=rec.id
But it doesn't list the receptions with no payment.
Please help me. Thanks in advance.
you need to Left Join the payment table:
from liquidation.reception rec
left join liquidation.payment pay on ( pay.recepcion_id=rec.id)
That is because you need to learn to use left outer join and proper join syntax. Just don't use a comma in a from clause any more.
Here is the query you want:
select rec.id, rec.reception_date, rec.tin_lot, rec.client_id, rec.weight,
coalesce(pay.payment_made, 0) as payment_made
from liquidation.reception rec left outer join
liquidation.payment pay
on pay.recepcion_id = rec.id;

SQL, multiple email adresses problem

I've a user table (MySQL) with the following data
id email creation_date
1 bob#mail.com 2011-08-01 09:00:00
2 bob#mail.com 2011-06-24 02:00:00
3 john#mail.com 2011-02-01 04:00:00
4 john#mail.com 2011-08-05 20:30:00
5 john#mail.com 2011-08-05 23:00:00
6 jill#mail.com 2011-08-01 00:00:00
As you can see we allow email duplicates so its possible to register several accounts with the same email address.
Now I need to select all adresses ordered by the creation_date but no duplicates. This is easy (i think)
SELECT * FROM (SELECT * FROM users ORDER BY creation_date) AS X GROUP BY email
Expected result:
id email creation_date
2 bob#mail.com 2011-06-24 02:00:00
6 jill#mail.com 2011-08-01 00:00:00
3 john#mail.com 2011-02-01 04:00:00
But then I also need to select all other adresses, ie. all that are not present in the result from the first query. Duplicate are allowed here.
Expected result:
id email creation_date
1 bob#mail.com 2011-08-01 09:00:00
4 john#mail.com 2011-08-05 20:30:00
5 john#mail.com 2011-08-05 23:00:00
Any ideas? Perfomance is important because the real database is very huge
SELECT * FROM a
FROM users a
LEFT JOIN (SELECT email, MIN(creation_date) as min_date GROUP BY email)x ON
(x.email = a.email AND x.min_date=a.creation_date)
WHERE x.email IS NULL
In SQL server we would do a Select statement using a rank.
Here are some MYSQL samples:
How to perform grouped ranking in MySQL
http://thinkdiff.net/mysql/how-to-get-rank-using-mysql-query/
I hope this helps.