Retrieve data from Sql Table according to described scenario - mysql

I have a database table with following columns
Id, Name, Date (FORMAT: Y-m-d H:i:s)
Now I want to retrieve data of following form
Count Year
3 2013
5 2014
It is showing total no of records generated in different years
For example If I have following data:
1 Manish 2013-10-01 23:12:12
2 Tarun 2013-10-02 23:12:12
3 Pankaj 2014-10-02 23:12:12
4 Pankaj 2015-10-02 23:12:12,
Then it will return me following data:
Count Year
2 2013
1 2014
1 2015
Is it possible?

select count(*) as cnt,
year(date) year_of_date
from your_table
group by year_of_date

select year(date) as Year,count(*) as Total
from my_table
group by year(date)

Related

issues writing simple sql queries

I have recently started working with SQL and I am trying to write a query that will display all cities that has the highest volume and listing on a yearly basis.
this query is able to handle the year 2011 alone
select city, year, month,max(volume),max(listings)
from kaydata
where year = 2011
result
city year month max(volume) max(listings)
0 Abilene 2011 2 6505000.0 746.0
sample data
city year month volume listings
0 modak 2011 1 5380000.0 701.0
1 Abilene 2011 2 6505000.0 746.0
2 ipetu 2010 3 9285000.0 784.0
2 oyog 2010 4 7085000.0 204.0
desired result
city year month max(volume) max(listings)
0 Abilene 2011 2 6505000.0 746.0
1 ipetu 2010 3 9285000.0 784.0
If I understand correctly, this would achieve what you're after:
select city,year,month,volume,maxlisting from (
select * , row_number() over (partition by year order by volume desc) rn
, max(listing) over (partition by year) maxlisting
from kaydata
) t
where rn = 1

select rows in mysql with latest date for each quiz_id repeated multiple times

I have a table where each quiz ID is repeated multiple times. there is a date in front of each quiz id in each row. I want to select entire row for each quiz ID where date is latest with user. The date format is mm/dd/YYYY.
Sample -
USER_ID Quiz_id Name Date Marks .. .. ..
1 2 poly 4/3/2020 27
1 2 poly 4/3/2019 98
1 4 moro 4/3/2020 09
2 5 cat 4/12/2015 87
2 4 moro 4/3/2009 56
2 6 PP 4/3/2011 76
3 2 poly 4/3/2020 12
3 2 poly 5/3/2020 09
3 7 dog 4/3/2011 23
I want result look like this:Result
USER_ID Quiz_id Name Date Marks .. .. ..
1 2 poly 4/3/2020 27
1 4 moro 4/3/2020 09
2 5 cat 4/12/2015 87
2 4 moro 4/3/2009 56
2 6 PP 4/3/2011 76
3 2 poly 5/3/2020 09
3 7 dog 4/3/2011 23
You can use rank function to get the desired result:
Demo
SELECT A.* FROM (
SELECT A.*, RANK() OVER(PARTITION BY USER_ID,QUIZ_ID, NAME ORDER BY DATE DESC) RN FROM
Table1 A ORDER BY USER_ID) A WHERE RN = 1 ORDER BY USER_ID, QUIZ_ID;
I don't have MySQL installed so you will need to test and report back. The general idea is to identify the row of interest using max and a group by (table t). As the Date column appears to be text column (MySQL uses the format YYYY-MM-DD for dates) you will need to convert it to a date with str_to_date() so you can use the max() aggregate function. Finally, join with the original table (here table t2 to do the date conversion), as only the aggregate column(s) and columns named in the group by are well defined (in table t1), i.e.:
select USER_ID, Quiz_id, Date, Marks from (
select USER_ID, Quiz_id, max(str_to_date(Date, '%m/%d/%Y')) as Date2 from quiz group by 1, 2
) as t natural join (
select *, str_to_date(Date, '%m/%d/%Y') Date2 from Quiz
) as t2;
I don't recall off-hand but Date might be reserved word, in which case you will need to quote the column name, or ideally rename said column to use a better name.
Also, the original table is not in 3rd normal form as Quiz_id depends on Name. Quiz_id, as implied, should be a foreign key to a lookup table that holds the Name.

Check if instances have occurred minimum once, every year in a specific range

In MySQL I'm tasked with a big dataset, with data from 1970 to 2010.
I want to check for consistency: check if each instance occurs minimum one time per year. I took a snippet from 1970-1972 as example to demonstrate my problem.
input:
id year counts
-- ---- ---------
1 1970 1
1 1971 1
2 1970 3
2 1971 8
2 1972 1
3 1970 4
expected:
id 1970-1972
-- ----------
1 no
2 yes
3 no
I though about counting within the date range and then taking those out who had 3 counts: 1970, 1971, 1972. The following query doesn't force the check on each point in the range though.
select id, count(*)
from table1
WHERE (year BETWEEN '1970' AND '1972') AND `no_counts` >= 1
group by id
What to do?
You can use GROUP BY with CASE / inline if.
Using CASE. SQL Fiddle
select id,CASE WHEN COUNT(distinct year) = 3 THEN 'yes'ELSE 'No' END "1970-72"
from abc
WHERE year between 1970 and 1972
GROUP BY id
Using inline IF. SQL Fiddle
select id,IF( COUNT(distinct year) = 3,'yes','No') "1970-72"
from abc
WHERE year between 1970 and 1972
GROUP BY id
You can use a having clause with distinct count:
select `id`
from `table1`
where `year` between '1970' and '1972'
group by id
having count(distinct `year`) = 3
Do you expect this?
select id, count(*)
from table1
WHERE (year BETWEEN '1970' AND '1972')
group by id
having count(distinct year) = 3

Count occurrences of distinct values

I am trying to find a MySQL query that will display the number of occurrences of an ID value within a year.
Table:
a_id year
---- ----
1 2010
1 2011
1 2012
1 2012
1 2013
1 2014
1 2015
2 2010
2 2011
2 2013
2 2014
2 2014
2 2015
3 2010
3 2010
3 2011
Expected output:
a_id year occurrences
---- ----- -----------
1 2010 1
1 2011 1
1 2012 2
1 2013 1
1 2014 1
1 2015 1
2 2010 1
2 2011 1
2 2013 1
2 2014 2
2 2015 1
3 2010 2
3 2011 1
I'm trying with the something along the lines of following sql query, but it gives me nothing like the expected output. It's the 3rd column im struggling with.
SELECT a__id, year, count(distinct a_id) as occurrences
FROM table1
GROUP by year
ORDER by a_id
How can i create that 3rd column?
Scince you are grouping by a_id and year you of course get only 1 distinct value for group. Simply change count(distinct a_id) to count(*).
For example you get group:
1 2012
1 2012
Notice in this group distinct a_id values is 1. But you want count of all rows in group. With distinct you will get 1 as occurence in all groups.
EDIT:
Ok, I have missed that you are grouping only by year, so you should group by a_id also. The rest of the answer stays as is. So you end up with:
SELECT a__id, year, count(*) as occurrences
FROM table1
GROUP by a__id, year
SELECT a__id, year, count(*) as occurrences
FROM table1
GROUP by a__id, year
Using the following will get you what you are looking for.
SELECT a_id, year, count(*)
FROM table1
GROUP BY a_id, year
ORDER BY a_id, year
Although, in previous versions, ORDER BY may have been guaranteed by MySQL, it is deprecated now. If you want to ensure your results come back sorted, add ORDER BY. 'Future you' will thank you for it.

Get personal and total worked hours in the same query

I have the following table (simplified):
user_id date hours
1 2012-03-01 5
2 2012-03-01 8
3 2012-03-01 6
1 2012-03-02 3
3 2012-03-02 7
What I want is to get the the sum of hours worked for a given user id (ex. 1), and the total hours worked regardless of what user (for a given time period) in a single query.
So for user_id = 1, and time period: 2012-03-01 - 2012-03-02 the query should return: own=8, total=29.
I can do it in two separate queries, but not in a single one.
Use CASE:
SELECT SUM(
CASE user_id
WHEN 1 THEN hours
ELSE 0
END) as Own,
SUM(hours) as Total
FROM HoursWorked
WHERE date BETWEEN '2012-03-01' AND '2012-03-02';
I think I have something that works using the following schema:
CREATE TABLE hoursWorked
(
id int,
date date,
hours int
);
INSERT INTO hoursWorked
(id, date, hours)
VALUES
('1','2012-03-01','5'),
('2','2012-03-01','8'),
('3','2012-03-01','6'),
('1','2012-03-02','3'),
('3','2012-03-02','7');
And this query:
select parent.id, parent.date, parent.hours, (select sum(hours)
from hoursWorked child
where child.id = parent.id) as totalHours
from hoursWorked parent
I was able to get these results:
ID DATE HOURS TOTALHOURS
1 March, 01 2012 00:00:00-0800 5 8
2 March, 01 2012 00:00:00-0800 8 8
3 March, 01 2012 00:00:00-0800 6 13
1 March, 02 2012 00:00:00-0800 3 8
3 March, 02 2012 00:00:00-0800 7 13
Diego's answer albeit procedural is a great way to get the answer you are looking for. Of course for your date range you would need to add a WHERE date BETWEEN 'startdate' AND 'enddate'. The dates need to be in a format that mysql recognizes, typically 'yyyy-mm-dd'
Another solution that doesn't get you the results in one row, but in a result set would be to do a UNION
SELECT user_id, SUM(hours) as hours FROM table WHERE date BETWEEN 'startdate' AND 'enddate' WHERE user_id = 3
UNION
SELECT null as user_id, SUM(hours) as hours FROM table WHERE date BETWEEN 'startdate' AND 'enddate'