I need to get Month number from event table using a mysql select query. here my EVENT table,
query
SELECT month(str_to_date(month,'%d')) AS m FROMevent``
but the result was
how can I convert my month column as numeric..
Use %M insted of %d
mysql> SELECT month(str_to_date('April','%M')) AS m;
+------+
| m |
+------+
| 4 |
+------+
1 row in set (0.05 sec)
Related
I think the short answer to this is No, but is it possible to emulate a recursive CTE with something like a table function in a database that doesn't have support for a CTE? For example:
-- get weekday names -- 'Monday', 'Tuesday', ...
WITH cte_numbers(n, weekday) AS (
SELECT
0,
DATENAME(DW, 0)
UNION ALL
SELECT
n + 1,
DATENAME(DW, n + 1)
FROM
cte_numbers
WHERE n < 6
)
SELECT
weekday FROM cte_numbers;
For example could the above pattern be rewritten to run in Mysql5.7, or recursion cannot be emulated there?
None of the solutions is very efficient, and most of them involve writing more code than you should. It would be better to upgrade to MySQL 8.0.
SQL works best on sets, not on iteration. So the standard way to generate a series in a single query is to already have a set of rows in a temporary table, and apply some set-based operations to it.
For example:
SELECT 0 AS num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5;
+-----+
| num |
+-----+
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+-----+
With this as the basis, you can do date arithmetic and then extract the weekday names with DATE_FORMAT():
SELECT DATE_FORMAT(CURDATE() + INTERVAL num DAY, '%W') AS weekday
FROM (
SELECT 0 AS num UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5
) AS t;
+-----------+
| weekday |
+-----------+
| Friday |
| Saturday |
| Sunday |
| Monday |
| Tuesday |
| Wednesday |
+-----------+
You could also prepare a fixed base table of integers, fill it with as many as you need, and use it for different purposes.
SELECT DATE_FORMAT(CURDATE() + INTERVAL num DAY, '%W') AS weekday
FROM MySetOfIntegers
WHERE num BETWEEN 0 AND 5;
The suggestion of using an iterative approach would involve writing a lot more code. It will also mean N SQL queries, each generating a separate result set, so that's more code you have to write in your application to fetch all the result sets and append them together.
You could write a recursive stored procedure, but there's a risk of exceeding the thread stack space if you allow deep recursion. The default limit on stored procedure recursion is 0. That is, no recursion is allowed at all unless you set a finite limit. See https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_max_sp_recursion_depth
Here's an example of a recursive stored procedure:
DROP PROCEDURE IF EXISTS Weekdays;
DELIMITER //
CREATE PROCEDURE Weekdays(IN date DATE, IN num INT)
BEGIN
IF num >= 1 THEN
CALL Weekdays(date, num-1);
END IF;
SELECT DATE_FORMAT(date + INTERVAL num-1 DAY, '%W') AS weekday;
END//
DELIMITER ;
And calling it. Note it produces multiple result sets.
mysql> set max_sp_recursion_depth=6;
mysql> call Weekdays(CURDATE(), 6);
+----------+
| weekday |
+----------+
| Thursday |
+----------+
1 row in set (0.00 sec)
+---------+
| weekday |
+---------+
| Friday |
+---------+
1 row in set (0.00 sec)
+----------+
| weekday |
+----------+
| Saturday |
+----------+
1 row in set (0.00 sec)
+---------+
| weekday |
+---------+
| Sunday |
+---------+
1 row in set (0.00 sec)
+---------+
| weekday |
+---------+
| Monday |
+---------+
1 row in set (0.00 sec)
+---------+
| weekday |
+---------+
| Tuesday |
+---------+
1 row in set (0.00 sec)
+-----------+
| weekday |
+-----------+
| Wednesday |
+-----------+
1 row in set (0.00 sec)
I may have gotten the recursion off by one somewhere. This actually supports the point that it's not as easy as it sounds to implement a recursive routine.
Oh and you get an error — and no results — if you exceed the recursion limit.
mysql> call Weekdays(CURDATE(), 8);
ERROR 1456 (HY000): Recursive limit 6 (as set by the max_sp_recursion_depth variable) was exceeded for routine Weekdays
Trying to see what's in a column I ended up doing some counting.
The table has 3981 rows.
But the counted column only shows a much lower number in total of its null and non null values.
How come ?
MariaDB [mydb]> select count(naf) from client where naf is not null;
+------------+
| count(naf) |
+------------+
| 83 |
+------------+
1 row in set (0.01 sec)
MariaDB [mydb]> select count(naf) from client where naf is null;
+------------+
| count(naf) |
+------------+
| 0 |
+------------+
1 row in set (0.01 sec)
MariaDB [mydb]> select count(*) from client;
+----------+
| count(*) |
+----------+
| 3981 |
+----------+
1 row in set (0.01 sec)
The following query is misleading you:
select count(naf) from client where naf is null;
The COUNT function ignores all NULL values. Hence, this query would never return any value other than zero. In reality, there are 3898 NULL records in the client table. To count nulls, you can try using the SUM function instead:
SELECT SUM(1) FROM client WHERE naf IS NULL;
This should be returning a sum of 3898.
I'm learning basic MYSQL and I want to get only the less value in this query.
Select DATE_FORMAT(CURDATE(),'%Y') - DATE_FORMAT(HIRE_DATE,'%Y') from employees;
Is there any function that do that?
EDIT:
I found the solution by myself. If someone wants to see is like that:
select MIN(timestampdiff(year,HIRE_DATE,CURDATE())) as LessYearsWorking FROM employees;
For getting the least you have a least function
mysql> select least(year(curdate()),year('2014-01-01')) as l;
+------+
| l |
+------+
| 2014 |
+------+
1 row in set (0.04 sec)
And for getting the difference in years between 2 dates you can use timestampdiff
mysql> select timestampdiff(year,'2014-01-01',curdate()) as d ;
+------+
| d |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
Combining both of them and getting the difference and also the least value in the same query could be done as
select
timestampdiff(year,'2014-01-01',curdate()) as d,
least(year(curdate()),year('2014-01-01')) as l ;
So your query becomes
select
timestampdiff(year,HIRE_DATE,curdate()) as diff,
least(year(curdate()),year(HIRE_DATE)) as least_date
from employees
I am trying to create a query to only show people who are older than 50 years of age, but i am having difficulty as I only have DOB and not an age field.
Any suggestions? Thanks
Assuming that you save the DOB in date or datetime datatype you can use timestampdiff as
select * from table_name
where timestampdiff(year,dob,curdate()) > 50
Here is a test case
mysql> select timestampdiff(year,'1960-01-20',curdate()) as age ;
+------+
| age |
+------+
| 55 |
+------+
1 row in set (0.00 sec)
mysql> select timestampdiff(year,'1950-01-20',curdate()) as age ;
+------+
| age |
+------+
| 65 |
+------+
1 row in set (0.00 sec)
Assuming dob column Datatype is DateTime
SELECT *
FROM tblname
where YEAR(CURDATE()) - YEAR(dob) > 55
DEMO SQL FIDDLE
Is it possible to configure MySQL to return TIMESTAMP value as a UNIXTIMESTAMP by default, rather than casting every column in the SELECT statement?
MySQL has a function to convert a date to a unix timestamp.
https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_unix-timestamp
mysql> SELECT UNIX_TIMESTAMP();
-> 1196440210
mysql> SELECT UNIX_TIMESTAMP('2007-11-30 10:30:19');
-> 1196440219
You cannot do that in MySQL configuration.
You can do that on application level - e.g. in PHP, you can use the mysqli_result::fetch_fields() method to detect timestamp type and convert it, other connectors will have similar methods.
Or you can do it - as suggested - using UNIX_TIMESTAMP() function on timestamp columns.
It sounds as though you want a different view of the same data:
mysql> select * from t;
+------+---------------------+
| data | ts |
+------+---------------------+
| foo | 2013-03-19 16:54:45 |
+------+---------------------+
1 row in set (0.00 sec)
mysql> select data, unix_timestamp(ts) from t;
+------+--------------------+
| data | unix_timestamp(ts) |
+------+--------------------+
| foo | 1363712085 |
+------+--------------------+
1 row in set (0.00 sec)
mysql> create view tv (data, time_t) as select data, unix_timestamp(ts) from t;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tv;
+------+------------+
| data | time_t |
+------+------------+
| foo | 1363712085 |
+------+------------+
1 row in set (0.00 sec)