Mysql - selecting year from a unix timestamp - mysql

I am using this:
SELECT FROM_UNIXTIME(my_unix_timestamp_column, '%Y') AS year FROM table_name WHERE year = 2009;
but it gives me an error:
Unknown column 'year' in 'where clause'SELECT FROM_UNIXTIME(my_unix_timestamp_column, '%Y') AS year FROM table_name WHERE year = 2009
Both "my_unix_timestamp_column" and "table_name" are correct, i dont know why it gives me this!!!
I'm using PHP 5.3.0

I'm not quite sure whether this is due to YEAR being a reserved word in MySQL or because it wants you to do something along the lines of:
SELECT
FROM_UNIXTIME(my_unix_timestamp_column, '%Y') AS year
FROM
table_name
WHERE
FROM_UNIXTIME(my_unix_timestamp_column, '%Y') = 2009;
Can't remember whether the last issue is only relevant to GROUPings :S

SELECT FROM_UNIXTIME(my_unix_timestamp_column, '%Y') AS `year`
FROM table_name
HAVING `year` = 2009
Unlike WHERE clause, HAVING clause can reference the SELECT clause aliases.
More index efficient way would be:
SELECT FROM_UNIXTIME(my_unix_timestamp_column, '%Y') AS `year`
FROM table_name
WHERE my_unix_timestamp_column >= UNIX_TIMESTAMP('2009-01-01')
AND my_unix_timestamp_column < UNIX_TIMESTAMP('2010-01-01')

Another alternative, avoiding repetition of a biggish function call:
SELECT year
FROM (SELECT FROM_UNIXTIME(my_unix_timestamp_column, '%Y') AS year
FROM table_name) AS list_of_years
WHERE year = 2009;
You might still need to use back-quotes around the word 'year' to avoid conflicts with YEAR as a keyword. The optimizer should not need to create an intermediate table to answer this query.

You can't use a column created the SELECT section in your WHERE clause
replace the year variable in your where clause with the actual function to create that column (aka FROM_UNIXTIME(my_unix_timestamp_column, '%Y') ) and you should be fine.
This is because the SELECT section of your query isn't executed until the WHERE section has finished matching rows to return.

The WHERE part is executed before the aliasing in the field list. Best thing is to use BETWEEN in the WHERE clause so an index can be used.

I haven't tried it myself, but would this work?
SELECT YEAR(my_unix_timestamp_column) AS 'year'
FROM table_name
WHERE YEAR(my_unix_timestamp_column) = 2009;
Ref link: https://www.w3schools.com/sql/func_mysql_year.asp

Related

MySQL return summed values and a virtual column as (count - sum)

I have a table as follows:
log (log_id, log_success (bool), log_created)
I would like to SELECT and return 3 columns date success and no_success, where the former does not exist in table and finally aggregate them by day.
I have created this query:
SELECT
log_created as 'date'
COUNT(*) AS 'count',
SUM(log_success) AS 'success'
SUM('count' - 'success') AS 'no_success'
FROM send_log
GROUP BY DATE_FORMAT(log_created, '%Y-%m-%d');
Would I be able to achieve it with this query? Is my syntax correct?
Thanks.
You can't reuse an alias defined in the select within the same select clause. The reason for this is that it might not even have been defined when you go to access it. But, you easily enough can repeat the logic:
SELECT
log_created AS date,
SUM(log_success) AS success,
COUNT(*) - SUM(log_success) AS no_success,
FROM send_log
GROUP BY
log_created;
I don't know why you are calling DATE_FORMAT in the group by clause of your query. DATE_FORMAT is usually a presentation layer function, which you call because you want to view a date formatted a certain way. Since it appears that log_created is already a date, there is no need to call DATE_FORMAT on it when aggregating. You also should not even need in the select clause, because the default format for a MySQL date is already Y-m-d.
You must select DATE_FORMAT(log_created, '%Y-%m-%d') if you want to group by this.
Also you can get the no_success counter with SUM(abs(log_success - 1))
SELECT
DATE_FORMAT(log_created, '%Y-%m-%d') date,
SUM(log_success) log_success,
SUM(abs(log_success - 1)) no_success
FROM send_log
GROUP BY date;
See the demo

Mysql: Using str_to_date on a select query returns nothing

I've following Mysql query:
select str_to_date((select distinct cast(substr(tb2.sub1,1,4) AS CHAR) as year from (
SELECT SUBSTRING_INDEX(file_name,'_',-1) as sub1 from table2) as tb2) , '%Y')
And it is correct because mysqlworkbench returns green flag but no output.
Could you help me?
The expression
select str_to_date('2007', '%Y')
returns 2007-00-00. Some MySQL servers are set to disallow invalid dates. Try using
select makedate('2007', 1)
instead. That will give you the valid date of 2007-01-01.
I'm leaving it to you to edit your query to make the change.

SQL INSERT INTO SELECT Statement Invalid use of group function

I've the following query:
INSERT INTO StatisticalConsultationAgreement VALUES (
queryType, entityCode, entityType, queryClass,queryTables,period,
COUNT(queryClass), SUM(numberRecords), SUM(recordsFound),
SUM(NorecordsFound), NOW(), 'system');
SELECT
MONTH(EndDateTimeProcessing),YEAR(EndDateTimeProcessing),
entityType,
entityCode,
queryType,
queryClass,
EndDateTimeProcessing as period
FROM agreementFile
WHERE
MONTH(EndDateTimeProcessing)=MONTH(DATE_SUB( CURDATE(), INTERVAL 1 MONTH ))
AND YEAR(EndDateTimeProcessing)=YEAR(CURDATE())
GROUP BY entityType,entitycode,queryType, queryClass;
When I run the query I get the next mistake:
Error code 1111, SQL state HY000: Invalid use of group function
Line 1, column 1
Executed successfully in 0,002 s.
Line 5, column 2
why ocurre this?
how to fix it?
You are mixing a values statement with a select statement in insert. You only need select. This is my best guess on what you want:
INSERT INTO StatisticalConsultationAgreement
SELECT queryType, entityCode, entityType, queryClass,queryTables,period,
COUNT(queryClass), SUM(numberRecords), SUM(recordsFound),
SUM(NorecordsFound), NOW(), 'system'
FROM agreementFile
WHERE MONTH(EndDateTimeProcessing)=MONTH(DATE_SUB( CURDATE(), INTERVAL 1 MONTH )) AND
YEAR(EndDateTimeProcessing)=YEAR(CURDATE())
GROUP BY entityType, entitycode, queryType, queryClass;
However, you should also list the column names for StatisticalConsultationAgreement in the insert statement.
You are not grouping EndDateTimeProcessing and when you try to do the Insert it can't figure out which EndDateTimeProcessing value, from the grouped rows, it should take.
The solution is either you add it on your group clause:
GROUP BY entityType,entitycode,queryType, queryClass, EndDateTimeProcessing;
Or you use a function group as MAX(), MIN(), etc.
Best Regards
EDIT
As said by Gordon Linoff, you are also mixing the query with the INSERT, everything should be gotten by the query.
The right syntax should be:
INSERT INTO StatisticalConsultationAgreement
SELECT
'queryType', --I don't know what is the query type so i put it on single quote
entityCode,
entityType,
queryClass,
queryTables,
MAX(EndDateTimeProcessing), --Period put on group function MAX, but it cant be grouped below or put into another group function
COUNT(queryClass), --
SUM(numberRecords), -- ASUMING THOSE ARE COLUMNS IN agreementFile
SUM(recordsFound), --
SUM(NorecordsFound),--
NOW(),
'system'
FROM agreementFile
WHERE
MONTH(EndDateTimeProcessing)=MONTH(DATE_SUB( CURDATE(), INTERVAL 1 MONTH ))
AND YEAR(EndDateTimeProcessing)=YEAR(CURDATE())
GROUP BY entityType,entitycode,queryType, queryClass;
The fields MONTH(EndDateTimeProcessing),YEAR(EndDateTimeProcessing), for the query were removed because i didn't know where thouse should be

splitting date and inserting individual field in separate column in mysql

i have created a date table directly through phpmyadmin and i want to split the date(yyyy:mm:dd) into individual day, month and year and insert into separate field. Can anybody help me in the query used directly in phpmyadmin to perform above work?
Try:
UPDATE `table` SET `year` = YEAR(`date`), `month` = DATE_FORMAT(`date`, '%m'), `day` = DATE_FORMAT(`date`, '%d')
I've used DATE_FORMAT() rather than MONTH() and DAY() as the latter two remove leading zeros.

Date Difference in MySQL to calculate age

I have a problem regarding the datediff MYSQL function, I can use it and it is simple. But I don't understand how to use it to collect differences within the table field. E.g.
I have a column dob and I want to write a query that will do something like
select dateDiff(current_timeStamp,dob)
from sometable 'here dob is the table column
I mean I want the difference from the current date time to the table field dob, each query result is the difference, the age of the user.
You mean like this?
SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF(NOW(), dob)), "%Y")+0 AS age from sometable
(Source)
You could do this
SELECT TIMESTAMPDIFF(YEAR, date_of_birth, NOW()) ASageFROM your_table
Works everytime.
If you want, for each user, display the age in years, do
select name,extract(year from (from_days(dateDiff(current_timestamp,dob))))
from sometable;
If I understand your comments on the previous answers, the date-of-birth column is not actually a DATE value but a string in the format m/d/y. I strongly recommend you change this; it slows down any date computations you want to do and you risk invalid date values getting entered into the column.
I think this is what you need. It uses the STR_TO_DATE() function and an algorithm for computing the age from the MySQL documentation:
SELECT YEAR(CURDATE()) - YEAR(STR_TO_DATE(dob, '%m/%d/%Y'))
- (RIGHT(CURDATE(), 5) < RIGHT(STR_TO_DATE(dob, '%m/%d/%Y'), 5)) AS age
FROM sometable;
I think this should help
SELECT DATE_FORMAT(FROM_DAYS(TO_DAYS(now()) - TO_DAYS(#dateofbirth)), '%Y') + 0;
Note: Give the D.O.B in the correct format, E.g. YYYY-MM-DD'=> '1991-11-11
Try this
SELECT DATEDIFF(CURDATE(), '2014-02-14');
select truncate(datediff(curdate(),dob)/365.25,0) from table;