I have a huge table of 2.000.000 rows in which I have two columns that are dates. Now I want to find all those rows where the difference between the two dates is > 30.
I have already set a query of this sort:
SELECT DATEDIFF(date1, date2) as new
FROM table1;
and it works and list all the results and shows the difference. Now, I would like to have as a result only those cases where the difference between the two dates is higher than 30, and also have the evidence of this number.
I have tried
SELECT DATEDIFF(date1, date2) >30 as new
FROM table1;
But as a result in column new I have always value 1 (which I think stands for TRUE), but I need to see this difference (the number: 31, 32, 33 ecc.).
Can someone please help me?
thank you
If I'm not mistaken, try
SELECT datediff(date1, date2) AS new FROM table1 WHERE new > 30;
The > operator can be used as a boolean and is comparing your datediff() and your 30. That's why you should place it in a WHERE statement, to prevent a boolean value in your select.
select datediff(date1;date2) >30 as new from table1
gives values: 1 because, it returns whether datediff(date1;date2) > 30is true or not!
Try this
SELECT datediff(date1;date2) as new FROM table WHERE datediff(date1;date2) >30;
SELECT DATEDIFF(date1, date2) as new
FROM table1
WHERE DATEDIFF(date1, date2) > 30;
Related
I have a column(varchar) with date values, I need to find those dates which are expiring in next 30 days.
ExpiringDate
===================
20171208,
20171215,samples
20171130,tested
N/A
No
(empty row)
So, First I need to get values before comma. On the resultset, I need to filter out rows that has only numbers(no 'N/A' or 'No' or empty rows) & then I need to filter those dates which are expiring in next 30 days.
Edited
I have tried the following & resultset seems to be inappropriate
SELECT
DocName,
CategoryName,
AttributeName,
CAST(SUBSTRING_INDEX(AttributeValue, ',', 1) AS DATE) AS ExpiredDate
FROM myDB
WHERE (AttributeName = 'Date of last vessel OVID' OR AttributeName = 'Next Statutory docking' OR
AttributeName = 'Last statutory docking') AND AttributeValue LIKE '%[^0-9]%' AND
DATEDIFF(now(), AttributeValue) <= 30;
Because you are not only storing dates as text, but mixing those dates with entirely non date information, this complicates things. In this case, we can do two checks, one to ensure that the record starts with an actual expected date, and the second to make sure that the date diff is within 30 days from now.
SELECT ExpiringDate
FROM
(
SELECT ExpiringDate
FROM yourTable
WHERE ExpiringDate REGEXP '^[0-9]{8}'
) t
WHERE
DATEDIFF(LEFT(ExpiringDate, 8), NOW()) BETWEEN 0 AND 30;
Note that I use a subquery to first remove rows that do not even have a parseable date. The reason for this is that DATEDIFF will error out if not passed valid dates for both parameters.
Demo
With MySQL, I need to find rows where two values are between two columns.
For example, I'm creating a schedule from '15:00' to '18:00', but the query must verify if any row has an period in use. If there is a record from '14:00' to '18:30', I need to return it to validate.
I tried something like, but not works:
select * from availabilities where (('15:00' or '18:00') between start_hour and end_hour)
Any idea?
This is basically a "test if range overlaps another range" question. The following query should work as long as start time is less than end time:
SELECT *
FROM availabilities
WHERE '18:00' > start_hour AND end_hour > '15:00'
You can use TIME() function to extract the time part of the datatime/timestamp column
Eg.
SELECT * FROM Table
WHERE TIME('timeStampCol') BETWEEN '12:00:00' AND '18:00:00'
I hava a table with sample forex one minute bar quotes.
id,quote_name,quote_date,quote_time,open_rate,close_rate,high_rate,low_rate
"1417","EURUSD","2015-01-01","13:01:00","1.2096","1.2096","1.2097","1.2096"
"1418","EURUSD","2015-01-01","13:02:00","1.2097","1.2096","1.2097","1.2096"
"1419","EURUSD","2015-01-01","13:04:00","1.2096","1.2098","1.2101","1.2096"
"1420","EURUSD","2015-01-01","13:05:00","1.2099","1.2099","1.2099","1.2099"
Is it possible to create select statement which will be return 5 minute interval quotes. I mean that it should select 5 rows between each 5 minut interval and return open_rate from first row, close_rate from last quote, and min and max of high_rate and low_rate.
Is it possible at all? How to do that.
What I know is that how to select min and max value between two dates.
Getting the five-minute interval is a bit of a pain. One way is to convert to seconds and divide by 300. Then, getting the first and last is also tricky. In this case, I would suggest a trick using substring_index() and group_concat():
select quote_date, min(open_time) as open_time,
substring_index(group_concat(open_rate order by quote_time), ',', 1) as first_open,
substring_index(group_concat(close_rate order by quote_time desc), ',', 1) as last_close,
min(high_rate), max(high_rate),
min(low_rate), max(low_rate)
from quotes
group by quote_date, floor(to_seconds(quote_time) / 300);
Suppose I have INT column, and I am using -1 to signify that no data was available at the time of the INSERT. I'd like to get an AVG of all values of this column that are 0 or larger.
Is this possible?
Thanks.
I forgot to mention that I'm doing this alongside other AVG's, so it's select avg(a), avg(b), avg(d) from tab; ... so I can't use b>0... because the others need to use the row data regardless of this one column's data being -1.
It occurs to me though that I could augment the AVG result e.g. if it would normally be (4 + 5 + -1 + -1 + 6) / 5. But if I know how many -1's there are I could "fix" the result to exclude them.
This might help:
If you want to ignore the -1 values from the average:
SELECT AVG(`a`), AVG(IF(`b` > -1, `b`, NULL)), AVG(`c`) FROM `t`;
If you want to consider the -1 values in the average:
SELECT AVG(`a`), AVG(IF(`b` > -1, `b`, 0)), AVG(`c`) FROM `t`;
I've assumed dummy column- and table- names and assumed column b as the one for which you want to consider only values >= 0. Please feel free to put in names as per your schema.
SELECT AVG(`field`) FROM `table` WHERE `field` >= 0
Please use this:
SELECT AVG(Column),
SUM(IF(Column>0))/COUNT(IF(Column>0))
FROM Table
Could you do something as such
SUM(column) / COUNT(*) as Average FROM 'table' WHERE 'column' >= 0
http://upic.me/i/hq/capture.png
http://upic.me/i/3g/capture.png
I have the table that divide datetime to single field and set these field to index.
i would to use where clause in date range ex. between 2010/06/21 to 2011/05/15
I try to use
where concat_ws('-',year,month,day) between '2010/06/21' and '2011/05/15'
it's work because I use concat function to adjust these field like ordinary datetime
but it not use index and query slowly.This table has 3 million record
if would to use index I try to this query
where
year = '2011'
and month between 05 and 06
and day between 21 and 15
It almost work but in last line
day between 21 and 15
I can't use this condition
I try to solve this problem but I can't find it and change structer table
I'm looking for answer
thank you
Now I can OR operation for query thank for your answer
In another case if would to find 2009/08/20 to 2011/04/15 It's use longer query and make confusion.Has someone got idea?
If it's a datestamp type, you can just use the where/between clause directly. I would consider switching to that, it's quite faster than a varchar with a custom date format.
WHERE yourdate BETWEEN "2011-05-01" AND "2011-06-15"
Although checking ranges may work for single months, you will find if you're querying between several months to have some margin of error because, if you think about it, you're selecting more than you may necessarily want. Using Datestamp will fix performance and usability issues arising from storing the date in a custom varchar.
Here are the two queries to convert your times around if you're interested:
ALTER TABLE `yourtable` ADD `newdate` DATE NOT NULL;
UPDATE `yourtable` SET `newdate` = STR_TO_DATE(`olddate`, '%Y/%m/%d');
Just change "yourtable", "newdate", and "olddate" to your table's name, the new date column name, and the old datestamp column names respectively.
If you can't change the table structure, you could use something like the following:
WHERE year = '2011'
AND ((month = '05' AND day >= 21) OR (month = '06' AND day <= '15'))
(At least, I think that query does what you want in your specific case. But for e.g. a longer span of time, you'd have to think about the query again, and I suspect queries like this could become a pain to maintain)
UPDATE for the updated requirement
The principle remains the same, only the query becomes more complex. For the range of 2009/08/20 to 2011/04/15 it might look like this:
WHERE year = '2009' AND (month = '08' AND day >= '20' OR month BETWEEN '09' AND '12')
OR year = '2010'
OR year = '2011' AND (month BETWEEN '01' AND '03' OR month = '04' AND day <= '15')
where year = 2011
and (month between 5 and 6) and (day > 20 or day < 16)
You where seperating days and month whereas you must keep them together
parentheses must be set ...
Mike
It is important that you use OR otherwise it is nonsense