I have quite a complex MySQL query with a problem but I have narrowed the problem down to the SQL below. The problem is that the MySQL date functions (WEEK, YEAR etc.) don't accept the datetime stored in a user variable.
SELECT
#test := datetime
,datetime
FROM `agenda`
WHERE YEAR(#test) = 2011
This doesn't give me any results, however, the following SQL gives me results:
SELECT
#test := datetime
,datetime
FROM `agenda`
WHERE YEAR(datetime) = 2011
(datetime is a fieldname in the agenda table.)
What is the problem here?
In the first query you're attempting to set #test equal to the datetime fields value based on a WHERE clause that is itself referring to the value of #test.
Unless #test has a value up front then you can't expect this to produce any meaningful results.
Related
I need to create a query that will convert the datetime to a new timezone and group by this field. Is there a way to do this in rails, without receiving a ONLY_FULL_GROUP_BY error? The following gives me the error, because I am not grouping by a selected field.
result = eventReading.select(counts, m, b, min(datetime) As datetime).where(dateime: Time.now).group("DATE(SUBTIME(CONVERT_TZ(datetime, 'GMT', 'America/New_York').order("datetime ASC").all
you don't need subtime you can group by using
.group(
"date(convert_tz(datetime,'UTC','America/New_York'))"
)
I have the following SQL statement running against a MariaDB 10.1.26 with ~2.000 rows with instant results.
select value, datetime from Schuppen
where (value = (select min(value) from Schuppen where (measure = 'temp')
and datetime between '2018-11-01 00:00:00' and '2018-11-02 00:00:00'))
and datetime between '2018-11-01 00:00:00' and '2018-11-02 00:00:00';
When I use the following statement with variables for the datetime fields, the execution takes ~5.5 seconds.
set #startdate = cast('2018-11-01 00:00:00' as datetime);
set #enddate = cast('2018-11-02 00:00:00' as datetime);
select value, datetime from Schuppen
where (value = (select min(value) from Schuppen where (measure = 'temp')
and datetime between #startdate and #enddate))
and datetime between #startdate and #enddate;
The more data rows I have, the longer it takes to execute the statement. Seems like the variables change the behaviour of the statement somehow.
What's wrong here?
I use MySQL Workbench and #variables are very useful to query/search different tables for a given attribute. I ran into a similar issue. After scouring through different threads and trying different things, it worked well when I set the #variable to be of exactly the same type and same encoding as the column in the table(s) that I am searching for that variable.
For example:
SET #keyword = CONVERT(CAST("KEYWORD" AS CHAR(8)) USING ASCII);
In this case, the search column cname in my table customer is of type CHAR(8) and encoded using ASCII:
SELECT * FROM CUSTOMERS WHERE cname=#keyword;
If you have multiple tables to query, where cname is CHAR(10) in one and CHAR(8) in another, then you can do the following:
SET #keyword = "KEYWORD";
SELECT * FROM CUSTOMERS WHERE cname=CONVERT(CAST(#keyword AS CHAR(8)) USING ASCII);
SELECT * FROM EMPLOYEES WHERE cname=CONVERT(CAST(#keyword AS CHAR(10)) USING ASCII);
The problem is that the query optimizer does a bad job on finding a suitable index when using variables. This is a known issue.
If you use EXPLAIN on both queries, you will see the difference. Just try to avoid variables when not necessary.
For the first query, the optimizer "sees" the chosen values and decides an index can be perfectly used to satisfy the selected range more efficiently.
For the second query, the optimizer is unaware of the two values that define the range, and decides to fall back to a FULL SCAN instead.
I have a table that contains a column of type TIMESTAMP (which is stored in UTC). My server is currently in timezone 'America/New_York'. I have the following query:
SELECT * FROM table1 WHERE hour(time) > 5;
Which returns the expected output. I then want to change the server's timezone to something else (doesn't matter what) and I want to get the same output as when it was 'America/New_York'. Basically, I want a query that returns all rows where the hour of time in timezone 'America/New_York' is greater than 5, regardless of what the current server timezone is.
I know I could use:
SELECT * FROM table1 WHERE hour(convert_tz(time, ##session.time_zone, 'America/New_York')) > 5;
But I don't want to use variables (##session.time_zone) because I want this SELECT to be included in a view and views don't support variables.
Is there a way to force a TIMESTAMP to be converted to a specific timezone regardless of the current server's timezone?
UPDATE: I found a way to create a function and then call that function from within the view:
create function getTimeZone() returns VARCHAR(50) DETERMINISTIC NO SQL return ##session.time_zone;
This works fine, but I feel like it's a bit of a hack.
In one of my MYSQL databases, I have done the following query :
SELECT * FROM mytable WHERE date_column < 1971-01-01 AND date_column IS NOT NULL;
This returns about 3000 items where the date is shown as NULL in the mysql command line prompt, and in the IntelliJ IDEA mysql database editor.
The column has a DATE type.
The database is a copy of a prod database environment that has been running for a couple years.
How can a record end up in that state ? What is that state ? How can I fix it properly ?
PS: The < 1971/01/01 clause was just to filter the correct dates out of the query. If I just query on the IS NOT NULL clause, I still get these weird dates of course.
I am surprised this works. First, date constants should be surrounded by single quotes:
SELECT *
FROM mytable
WHERE date_column < '1971-01-01' AND date_column IS NOT NULL;
Second, this cannot return a NULL value for date_column. This suggests one of two things:
date_col is actually another type, such as varchar and you are seeing 'NULL' the string, not NULL the value.
another column is NULL.
Is there a way to trim off the timestamp in a DB2 date function?
Have DB2 select statement where I'mm selecting a date form the databease and saving it to a variable. I then use that variable as a parameter for another db2 select by adding 30days to it but I don't think it agrees with the timestamp that it is adding to the end.
Select business_date From DB2INST1.BusDate Where key = 0
There is no timestamp in the database for this date but its adding '12:00:00AM' to the end
it saves this select into a variable and I use it in another select here
where expirdate > (DATE(#BusDate) + 30 DAYS)
I get this error:
{"ERROR [428F5] [IBM][DB2/AIX64] SQL0245N The invocation of routine \"DATE\" is ambiguous. The argument in position \"1\" does not have a best fit."} System.Exception {IBM.Data.DB2.DB2Exception}
Select business date as a varchar/string
Select varchar_format(business_date,'YYYY-MM-DD')
then do this to use it later, convert it to a date then use a date function to add 30days to it:
(DATE(to_date(#BusDate, 'YYYY-MM-DD') + 30 DAYS))
Try
where expirdate > DATE(#BusDate + 30 DAYS)
Is the first SELECT statement and the second SELECT Statement part of same stored procedure? Are you storing the resulting date in any .Net variable? If you are storing it in a .Net DateTime variable, my suggestion is to do the date addition operation in .Net code itself. And then remove the time part from the variable before passing to the database.
Take a look at this too: Datetime field overflow with IBM Data Server Client v9.7fp5
If both the SELECT statements were part of a stored procedure and there is no .Net DateTime variable invloved, then it is a different story.