I have a table that has date and id column. How can I select id's of 7 days interval?
My data is:
date id
2013-07-01 11
2013-07-02 22
2013-07-03 33
2013-07-04 33
2013-07-05 44
2013-07-06 44
2013-07-07 45
2013-07-08 46
2013-07-09 47
2013-07-10 48
2013-07-11 48
2013-07-12 49
2013-07-13 50
2013-07-14 51
2013-07-15 52
2013-07-16 52
2013-07-17 53
2013-07-18 53
2013-07-19 54
What I want is:
date id
2013-07-01 11
2013-07-08 46
2013-07-15 52
Thanks
SELECT date,id FROM table1 GROUP BY WEEK(`date`, 1)
http://sqlfiddle.com/#!2/b128c/1
the group by does not do the trick with (any) sql - ok mysql does - others wont allow this
SELECT date,id FROM table1 GROUP BY WEEK(`date`, 1)
would result in something like error: id is not part of group by ....
if you group by a col1 and not by col2 the database does not know what value you want for col2.
MySql seems to assume "if i do not group by others, take the smallest or first in databsse order'
If - and only if - you want the first (!) result - or what ever MySql decides to use for your missing 2nd grouping element, you are ok.
explanation:
assume this:
CREATE TABLE table1
(`id` int, `val` int );
INSERT INTO table1
(`id`, `val`)
VALUES
(1,99), --'!!!!'
(1,2),
(1,3),
(1,4),
(1,2),
(2,1),
(1,1),
(2,2),
(3,1),
(4,1)
;
See - please, there a 6 rows with 'id'=1, two with id '2' others unique
select id, val FROM table1 GROUP BY id
evaluates to:
ID VAL
1 99
2 1
3 1
4 1
this is only - probably - what you want and if it is a date you have a chance(!) the it will be what you want
to get a valid (without database intepret) result set you will have to use:
select id, some_aggregation_function(val) from table1 group by id
where aggregation is min, max or so.
the is some thing like :
select id, val FROM table1 a
where (id,val)=(select id, min(val) from table1 b where a.id=b.id)
if you want the minimum ....
Related
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.
I have a table with the structure below with name table1
sid userid date result
1 169110 2020-01-03 (null)
2 178662 2020-01-06 (null)
3 165381 2020-01-07 (null)
5 368031 2020-01-08 (null)
7 163626 2020-01-09 (null)
Now I need to send each row values of cft.userid and cft.date to a mysql query (query is below) which gives the value of the result for each row
UPDATE collision_fact_table cft
SET cft.on_time_completion = (
SELECT DISTINCT
CONCAT(ROUND(NULLIF(SUM(facttable.compliant), 0) / NULLIF(SUM(facttable.Occurences), 0) * 100), '%') AS `Percentage Completed`
FROM fd_dw.ComplianceFactTable facttable
WHERE (CAST(facttable.`CourseModule_dueDateID` AS date) - cft.collision_date) <= 0
AND facttable.UserLicenseInUsing = 1
AND (facttable.`CourseModule_dueDateID` > 0)
AND facttable.UserId = cft.userid
GROUP BY facttable.`UserID`);
For example, when i send first row values of userid 169110 and date value to the above query, i will get result as 69 and i need to update 69 to the table1 like below
sid userid date result
1 169110 2020-01-03 69
Similarly it should iterate for all the rows and table1 should get updated like below
sid userid date result
1 169110 2020-01-03 69
2 178662 2020-01-06 55
3 165381 2020-01-07 64
5 368031 2020-01-08 48
7 163626 2020-01-09 56
But when i tried to execute the update query, its giving me error Unknown column 'cft.date' in field list
Please anyone help me
I think you basically want a correlated subquery:
update table1 t1
set result = (
select cd.result
from ...
where
cd.ScheduleDateID <= t1.date
and cd.CourseModuleComplete_DateID <= t1.date
and cd.UserId = t1.userid
)
You don't give much details about the subquery itself. It is critical that it should return one row, and one row only:
if it returns no rows, then the result of the corresponding row in table1 will be set to null (regardless of its original value) - this might, or might not be what you want
if it returns more than one row, then the query will error
I need to extract the required fields from a table along with relevant time stamp
SELECT * FROM Glm_Test.LicenseUsage where FeatureId='2';
Output :
VendorId,FeatureId,Total_Lic_Installed,Total_Lic_Used,Reserved,CurrentTime
1 2 106 19 67 2015-12-15 15:00:05
1 2 106 19 67 2015-12-15 15:02:02
1 2 106 19 69 2015-12-15 15:04:02
1 2 106 19 67 2015-12-15 15:06:01
1 2 106 20 67 2015-12-15 15:08:02
select VendorId,FeatureId,Total_Lic_Installed,Max(Total_Lic_Used),Reserved,CurrentTime from Glm_Test.LicenseUsage where FeatureId= '2' group by VendorId,FeatureId;
output:
1 2 106 20 69 2015-12-15 15:00:05
In the above 2 queries
1st query lists all entries from the table
and i want second query to return time stamp for the MAX value of column Total_Lic_Used but somehow it is returning me only timestamp of the first entry.
Help is much appreciated.
Selecting the columns which are not part of an aggregation function like count/max/min/sum... or not in group by clause will give unexpected results:
Other RBBMS wont allow these statements(gives error like):
sql server ==> the select list because it is not contained in either
an aggregate function or the GROUP BY clause
Oracle ==>not a GROUP BY expression
You can do this by a sub query and join
select
a.VendorId,
a.FeatureId,
a.Total_Lic_Installed,
b.max_Total_Lic_Used,
a.Reserved,
a.CurrentTime
from Glm_Test.LicenseUsage a
join (
select
VendorId,
FeatureId,
Max(Total_Lic_Used) max_Total_Lic_Used
from Glm_Test.LicenseUsage
where FeatureId = '2'
group by VendorId, FeatureId
) b
on a.VendorId = b.VendorId and
a.FeatureId = b.FeatureId and
a.Total_Lic_Used = b.max_Total_Lic_Used
sql fiddle demo
You can try this also;
select
`VendorId`,
`FeatureId`,
`Total_Lic_Installed`,
`Total_Lic_Used`,
`Reserved`,
`CurrentTime`
from Glm_Test.LicenseUsage
order by Total_Lic_Used desc
limit 1
demo
I need to find the length of time between 2 dates (datetime types) based on the unique ID. For example, I have the following data:
ID CallID Starttime
1 56 2011-01-04 10:00:00.000
1 67 2011-03-20 12:20:00.000
1 70 2011-04-08 15:00:00.000
2 57 2011-01-14 11:00:00.000
2 62 2011-02-14 11:00:00.000
2 64 2011-02-15 11:00:00.000
2 75 2011-04-14 11:00:00.000
2 78 2011-05-14 11:00:00.000
I need to find the length of time for all the CallIDs for each ID based on the previous call date (starttime). For example, I need the length of time for all the calls for ID 1 (CallID 67 - CallID 56 and CallID 70 - CallID 67, etc.).
I know I need a loop of some kind that would go through the IDs to find the CallIDs for that ID but do I also need a temporary table where I would organize the CallIDs?
Any suggestions would be appreciated. Thank you.
One way.
;WITH T
AS (SELECT ID,
CallID,
Starttime,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Starttime) RN
FROM YourTable)
SELECT t1.ID,
t1.CallID,
t2.CallID,
DATEDIFF(HOUR, t1.Starttime, t2.Starttime)
FROM T t1
INNER JOIN T t2
ON t1.RN = t2.RN - 1
AND t1.ID = t2.ID
I have a simple table called 'message' consisting of an 'id' column and a 'date' column. There can be multiple id's with the same value. I'm looking for a query that returns up to three of each id, and of those three they must be the ones with the greatest dates.
So the query would produce something like this:
id | date
--- -------------------
36 2011-04-01 08:41:19
36 2011-04-17 08:05:18
36 2011-04-17 18:48:49
39 2011-03-31 05:45:15
39 2011-03-31 05:50:07
39 2011-03-31 05:56:23
41 2011-04-11 07:02:27
41 2011-04-19 02:31:31
41 2011-04-19 02:32:53
etc...
I've been having trouble figuring this out.
select * from table as t1
where (select count(*) from table as t2
where t1.id = t2.id and t2.date > t1.date) < 3
order by id, date desc