This might be a simple one, but since I don't have much knowledge about MySQL I don't know how to do this, This is what I basically want,
I have a query like this
//time format "yyyy-MM-dd"
SELECT ID
FROM `id_table`
WHERE time > "2012-01-05 " AND time < "2012-01-10";
But in the id_table I have data only up to 2012-01-04 then it starts again from "2012-01-20", so above query would return null. Is there a any way where I can retrieve the last data record from the table, as for this example can I get the ID of 2012-01-04 date from the table when I query like this
SELECT ID
FROM `id_table`
WHERE time > "2012-01-05"
Are you looking for the one (i assume max ID) ID of the row with the nearest time to 2010-01-05?
SELECT MAX(ID) as LastId FROM id_table
WHERE time = (SELECT MAX(time)
FROM id_table WHERE time < '2012-01-05')
Try this:
SELECT ID FROM id_table
WHERE time between
least((select max(time) from id_table), "2012-01-05") AND "2012-01-10";
Note that between will get data from "2012-01-10" and ("2012-01-05" OR "2012-01-05)
To get the record closest to the given time ( you could easily tweak this if you care about dealing with duplicates, if that doesn't matter then this alone should suffice)
SELECT
ID
FROM
id_table
ORDER BY ABS(DATEDIFF(time, '2012-01-05'))
LIMIT 1
NOTE: If the time field is a time value yyyy-mm-dd hh:mm:ss then you can use TIMEDIFF for a more accurate comparison.
OP If you will explain more on how you would like to handle different cases I can tweak this example to suit them. Cheers.
Related
I have a MariaDB 10.2.21.
My table contains records that include a 'ChangeDate' field like this: '2019-09-18 10:57:26'.
I want to do a SELECT based on a timestamp, and get the nearest previous record to return.
This allows me to do a 'point-in-time' selection providing me with field values as they were at that moment.
I seeked StackOverflow but do no recognize a proper solution.
Any hints? Thanks!
Try following Query
SELECT *
FROM my_table
WHERE ChangeDate < '2019-09-18 10:57:26'
ORDER
BY ChangeDate DESC
LIMIT 1
I have 2 questions. First of all I have a MySQL Database with the rows: id(AUTO_INCREMENT PRIMARY KEY), name and time. This database represents the times of a race. I would like to select the name and time where the time is the smallest.
SELECT name, MIN(time) as time FROM race GROUP BY TIME;
This query gives me all times and names as long as there are no duplicates in the names. I however only want the fastest time and the name in that row.
Then when I submit my time i would like to know on what place I am. Will ORDER BY TIME keep each ID of each row the same or can I just ORDER table BY time and then select row where ID= 1?
If it's possible to have multiple entries with the same time, I would use a nested query like this, because limiting the result set to 1 may exclude a name.
select name, time from race where time = (select min(time) from race)
If you want to know what place a given time is in, just count the number of entries that have times less than it.
select count(*) + 1 as place from race where time < [your time]
For your first question, what you want is to select the 'least' time.
Here is, what I think, the clearest way to do that, which uses the LIMIT function to only return 1 row.
MySQL:
SELECT name, time
FROM race
ORDER BY time asc
LIMIT 1;
MS SQL:
SELECT TOP 1 name, time
FROM race
ORDER BY time asc
I have a table "A" with a "date" field. I want to make a select query and order the rows with previous dates in a descending order, and then, the rows with next dates in ascending order, all in the same query. Is it possible?
For example, table "A":
id date
---------------------
a march-20
b march-21
c march-22
d march-23
e march-24
I'd like to get, having as a starting date "march-22", this result:
id date
---------------------
c march-22
b march-21
a march-20
d march-23
e march-24
In one query, because I'm doing it with two of them and it's slow, because the only difference is the sorting, and the joins I have to do are a bit "heavy".
Thanks a lot.
You could use something like this -
SELECT *
FROM test
ORDER BY IF(
date <= '2012-03-22',
DATEDIFF('2000-01-01', date),
DATEDIFF(date, '2000-01-01')
);
Here is a link to a test on SQL Fiddle - http://sqlfiddle.com/#!2/31a3f/13
That's wrong, sorry :(
From documentation:
However, use of ORDER BY for individual SELECT statements implies nothing about the order in which the rows appear in the final result because UNION by default produces an unordered set of rows. Therefore, the use of ORDER BY in this context is typically in conjunction with LIMIT, so that it is used to determine the subset of the selected rows to retrieve for the SELECT, even though it does not necessarily affect the order of those rows in the final UNION result. If ORDER BY appears without LIMIT in a SELECT, it is optimized away because it will have no effect anyway.
This should do the trick. I'm not 100% sure about adding an order in a UNION...
SELECT * FROM A where date <= now() ORDER BY date DESC
UNION SELECT * FROM A where date > now() ORDER BY date ASC
I think the real question here is how to do the joining once. Create a temporary table with the result of joining, and make the 2 selects from that table. So it will be be time consuming only on creation (once) not on select query (twice).
CREATE TABLE tmp SELECT ... JOIN -- do the heavy duty here
With this you can make the two select statenets as you originally did.
This simple SQL problem is giving me a very hard time. Either because I'm seeing the problem the wrong way or because I'm not that familiar with SQL. Or both.
What I'm trying to do: I have a table with several columns and I only need two of them: the datetime when the entry was created and the id of the entry. Note that the hours/minutes/seconds part is important here.
However, I want to group my selection according to the DATE part only. Otherwise all groups will most likely have 1 element.
Here's my query:
SELECT MyDate as DateCr, COUNT(Id) as Occur
FROM MyTable tb WITH(NOLOCK)
GROUP BY CAST(tb.MyDate as Date)
ORDER BY DateCr ASC
However I get the following error from it:
Column "MyTable.MyDate" is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
If I don't do the cast in the GROUP BY, everything fine. If I cast MyDate to DATE in the SELECT and keep the CAST from GROUP BY, everything fine once more. Apparently it wants to keep the same DATE or DATETIME format in the GROUP BY as in the SELECT.
My approach can be completely wrong so I am not necessarily looking to fix the above query, but to find the proper way to do it.
LE: I get the above error on line 1.
LE2: On a second look, my question indeed is not very explicit. You can ignore the above approach if it is completely wrong. Below is a sample scenario
Let me tell you what I need: I want to retrieve (1) the DateTime when each entry was created. So if I have 20 entries, then I want to get 20 DateTimes. Then if I have multiple entries created on the same DAY, I want the number of those entries. For example, let's say I created 3 entries on Monday, 1 on Tuesday and 2 today. Then from my table I need the datetimes of these 6 entries + the number of entries which were created on each day (3 for 19/03/2012, 1 for 20/03/2012 and 2 for 21/03/2012).
I'm not sure why you're objecting to performing the CONVERT in both the SELECT and the GROUP BY. This seems like a perfectly logical way to do this:
SELECT
DateCr = CONVERT(DATE, MyDate),
Occur = COUNT(Id)
FROM dbo.MyTable
GROUP BY CONVERT(DATE, MyDate)
ORDER BY DateCr;
If you want to keep the time portion of MyDate in the SELECT list, why are you bothering to group? Or how do you expect the results to look? You'll have a row for every individual date/time value, where the grouping seems to indicate you want a row for each day. Maybe you could clarify what you want with some sample data and example desired results.
Also, why are you using NOLOCK? Are you willing to trade accuracy for a haphazard turbo button?
EDIT adding a version for the mixed requirements:
;WITH d(DateCr,d,Id) AS
(
SELECT MyDate, d = CONVERT(DATE, MyDate), Id
FROM dbo.MyTable)
SELECT DateCr, Occur = (SELECT COUNT(Id) FROM d AS d2 WHERE d2.d = d.d)
FROM d
ORDER BY DateCr;
Even though this is an old post, I thought I would answer it. The solution below will work with SQL Server 2008 and above. It uses the over clause, so that the individual lines will be returned, but will also count the rows grouped by the date (without time).
SELECT MyDate as DateCr,
COUNT(Id) OVER(PARTITION BY CAST(tb.MyDate as Date)) as Occur
FROM MyTable tb WITH(NOLOCK)
ORDER BY DateCr ASC
Darren White
Not sure how best to word this, so please bear with me. My table (simplified) is as follows:
id - Integer - auto increment
user_id - Integer
timestamp - Datetime
What I need is the ability to query this table and select all records where the timestamp columns are within a predefined time range (potentially arbitrary, but lets say 10 minutes) for each user_id.So, for example, I would like to know if there is an entry for hypothetical user_id 5 at "2011-01-29 03:00:00" and then next at "2011-01-29 03:02:00" but not if a user searched once at "2011-01-29 03:00:00" and then next at "2011-01-29 05:00:00". This would also need to capture instances where a user searches more than 2 times, each within the time range of the previous.
For background, this is a table of site searches, and I would like to know all instances where a user searches for something, then searches again (presumably because their previous search did not provide the results they were looking for).
I know this is probably simpler than I am making it out to be, but I can't seem to figure it out. I can clarify or provide additional info if needed. Thanks!
EDIT:
I am interested in the search returning results for all of the users in the table, not just user #5, and also to search without input of the actual times. The timestamp should not be something which is manually input, but should instead should find rows by each user which are within 10 minutes of one another.
SELECT distinct t1.user_id, t1.another_field, t1.another_field
FROM
table t1,
table t2
WHERE
t1.user_id = t2.user_id
AND abs(timestampdiff(MINUTE, t1.timestamp, t2.timestamp)) < 10
if you want to further limit the results, you can add
AND t1.user_id = any_number (or IN or between, etc)
To restrict date range add,
AND t1.timestamp BETWEEN A and B (or > or <)
This should give you all users and theirs number of searches within time limit:
SELECT user_id, COUNT(*) AS cnt FROM table
WHERE timestamp BETWEEN "2011-01-29 03:00:00" AND "2011-01-29 03:02:00"
GROUP BY user_id
ORDER BY user_id
This will show you number of searches made just by user_id #5:
SELECT COUNT(*) AS cnt FROM table
WHERE user_id=5
AND timestamp BETWEEN "2011-01-29 03:00:00" AND "2011-01-29 03:02:00"
Depending on actual DB the syntax might be somewhat different, especially the format of dates passed to BETWEEN condition.