need help on adding date column and int column - mysql

column1 = '2023-01-09' and column2 = '60'
select (column1 + column2) as column3
i need column3 as their sum but the value appears is 20230169 instead of 2023-03-09

You may use INTERVAL syntax here:
SELECT '2023-01-09' + INTERVAL 59 DAY; -- 2023-03-09
But it seems that you really just want to add 2 months:
SELECT '2023-01-09' + INTERVAL 2 MONTH; -- 2023-03-09

Related

I have a query written in Oracle , would like to convert into MySQL

select * from
(
select week_of, COUNT(DISTINCT CUSTOMER_ID) AS weekly_developer_count, COUNT(DISTINCT APPLICATION_ID) as weekly_app_count from
(
select PE.EVENT_DAY_UTC, to_char(next_day(PE.EVENT_DAY_UTC - 1, 'SUNDAY'), 'YYYY-MM-DD') as week_of, PE.CUSTOMER_ID, PE.APPLICATION_ID
from tablename PE
where
PE.EVENT_DAY_UTC >= SYSDATE - 90
and PE.EVENT_DAY_UTC < SYSDATE + 1
and PE.EVENT_NAME NOT LIKE '%.%'
)
group by week_of
)
order by week_of desc;
This is the code I have it in Oracle, MySQL doesn't support NEXT_DAY. Any idea to achieve this?
I want as the output something like
Weekof ApplicationCount DeveloperCount
2016-17-07 50 10
2016-10-07 60 15
You can implement your own function, like described here:
MySQL implementation of Oracle's next_day
You can probably replace next_day with an appropriate combination of date math and DAYOFWEEK, something like:
mydate + INTERVAL (8-DAYOFWEEK(mydate)) DAY
should work for Sunday
Here's a MySQL stored function you can define that does the same thing as Oracle's NEXT_DAY():
CREATE FUNCTION next_day (date DATE, dow VARCHAR(10)) RETURNS DATE
RETURN FROM_DAYS(
TO_DAYS(date) - DAYOFWEEK(date)
+ IF(DAYOFWEEK(date) >= FIND_IN_SET(dow, 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'), 7, 0)
+ FIND_IN_SET(dow, 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday')
);

All MySQL records from yesterday

What is an efficient way to get all records with a datetime column whose value falls somewhere between yesterday at 00:00:00 and yesterday at 23:59:59?
SQL:
CREATE TABLE `mytable` (
`id` BIGINT,
`created_at` DATETIME
);
INSERT INTO `mytable` (`id`, `created_at`) VALUES
(1, '2016-01-18 14:28:59'),
(2, '2016-01-19 20:03:00'),
(3, '2016-01-19 11:12:05'),
(4, '2016-01-20 03:04:01');
If I run this query at any time on 2016-01-20, then all I'd want to return is rows 2 and 3.
Since you're only looking for the date portion, you can compare those easily using MySQL's DATE() function.
SELECT * FROM table WHERE DATE(created_at) = DATE(NOW() - INTERVAL 1 DAY);
Note that if you have a very large number of records this can be inefficient; indexing advantages are lost with the derived value of DATE(). In that case, you can use this query:
SELECT * FROM table
WHERE created_at BETWEEN CURDATE() - INTERVAL 1 DAY
AND CURDATE() - INTERVAL 1 SECOND;
This works because date values such as the one returned by CURDATE() are assumed to have a timestamp of 00:00:00. The index can still be used because the date column's value is not being transformed at all.
You can still use the index if you say
SELECT * FROM TABLE
WHERE CREATED_AT >= CURDATE() - INTERVAL 1 DAY
AND CREATED_AT < CURDATE();
You can use subdate to indicate "yesterday" and use date() to indicate that you want records where just the date part of the column matches. So:
SELECT *
FROM tablename
WHERE DATE(created_at) = SUBDATE(CURRENT_DATE(), INTERVAL 1 DAY)
Here is the same question with an answer. To summarize answer for you, use subdate() as suggested by Sajmon.
subdate(currentDate, 1)
using your table it should be.
select *
from tablename
where created_at between subdate(CURDATE(), 1)
and date (now() )
use:
subdate(current_date, 1)
it's awesome for your case!
SELECT subdate(current_date(), 1)
SELECT * FROM table
WHERE created_at >= subdate(current_date(), 1)
You can use this, just put tablename and columnName (Which Contain 2021/01/09 or 2022-01-11 14:56:07 etc)
select * from (TABLENAME) where DATE(columnNAME) = TODAY - 1;

How can I filter a query by the hour portion of a DateTime field in MySQL?

I need to select rows from table, where e.g. time is >= 18:00:00 no matter of date. Problem is that value is datetime type so there is also date beside. e.g. 2012-01-25 18:00:00.
table1
======
row 1: id='1' datetime='2012-01-25 18:00:00'
row 2: id='2' datetime='2012-01-27 15:00:00'
row 3: id='3' datetime='2012-01-30 19:45:00'
I need to select row 1 and row 3.
Is there way to combine LIKE and >= to do time >= '% 18:00:00' where % represents whatever date?
You can use the TIME() function:
WHERE TIME(`datetime`) >= '18:00:00'
select *
from table1
where HOUR(datimetime) >= 18
Something like this maybe:
SELECT *
FROM yourTable
WHERE
EXTRACT(HOUR FROM YourDate)>18

Check existence of rows for last n days

I want to perform a check "is there an entry for each of the last 100 days in a table" where the table has something like a reference date column and was thinking about joining with a subquery that returns sysdate - 0, sysdate - 1, ... sysdate - 100.
Updates (for clarification):
I need to know which dates are missing in the last n days
I want to avoid additional tables (also temp tables)
Is this a good approach?
Assuming your Oracle table looks like this...
CREATE TABLE DATE_TABLE (
D DATE,
-- And other fields, PK etc...
)
...and assuming D contains "round" dates (i.e. no time-of-day), the following query will give you all the missing dates between :min_date and :min_date + :day_count:
SELECT *
FROM (
SELECT (TO_DATE(:min_date) + LEVEL - 1) GENERATED_DATE
FROM DUAL
CONNECT BY LEVEL <= :day_count
)
WHERE
GENERATED_DATE NOT IN (SELECT D FROM DATE_TABLE)
In plain English:
Generate all dates in given interval (the sub-query).
Check if any of them is missing from the table (the super-query).
This is what you are looking for:
Select seqnum.date, count(issues.id)
from
(
SELECT
Curdate() - interval (TENS.SeqValue + ONES.SeqValue) day Date
FROM
(
SELECT 0 SeqValue
UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5
UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) ONES
CROSS JOIN
(
SELECT 0 SeqValue
UNION SELECT 10 UNION SELECT 20 UNION SELECT 30 UNION SELECT 40 UNION SELECT 50
UNION SELECT 60 UNION SELECT 70 UNION SELECT 80 UNION SELECT 90
) TENS
) seqnum
left join issues on (cast(issues.created_on as date) = seqnum.date)
group by seqnum.date
I ran it against a Redmine instance to see how many issues were created in the last 100 days, day by day, including days where no issue was created. Adjust to your data structures accordingly. Enjoy :)
This might help you out:
create table your_table (a_date date not null);
insert into your_table values (date(now()-interval 0 day));
insert into your_table values (date(now()-interval 1 day));
insert into your_table values (date(now()-interval 2 day));
insert into your_table values (date(now()-interval 3 day));
insert into your_table values (date(now()-interval 5 day));
insert into your_table values (date(now()-interval 6 day));
insert into your_table values (date(now()-interval 9 day));
insert into your_table values (date(now()-interval 10 day));
insert into your_table values (date(now()-interval 50 day));
insert into your_table values (date(now()-interval 60 day));
insert into your_table values (date(now()-interval 70 day));
insert into your_table values (date(now()-interval 80 day));
insert into your_table values (date(now()-interval 90 day));
select a_date,ifnull(datediff(next_date ,a_date)-1,0) as number_of_days_missing_after_date
from
(
select dt.a_date,
(select min(a_date) from your_table dtp where dtp.a_date > dt.a_date and dtp.a_date >= date(now()-interval 100 day)) as next_date
from
(select a_date
from your_table
union select date(now()-interval 100 day)) dt
where dt.a_date >= date(now()-interval 100 day)
) a;
Should give you an indication as to which dates are missing.
I have created table your_table in place of the table that you are planning to check for missing dates (so that I could illustrate my example more clearly to you).
Perhaps the only problem with this solution is that it will not give you a list of the missing dates - though they can be easily derived by looking at the (in the example) a_date column and the number of days missing after a_date.
Hope it helps & good luck!
If there aren’t any gaps (e.g., weekends), a trick you can use is
SELECT COUNT(DISTINCT somedate)=100 FROM sometable -- evaluates to boolean
WHERE somedate>=sysdate-100;
Depending on your RDBMS, a GROUP BY may work faster than COUNT DISTINCT.
[Post clarification comment]
As you have explained it now, I think you want a LEFT JOIN between a dense date list and your table, then COUNT and GROUP BY. If you are using MySQL, the way to generate the date list in a subquery is covered by this earlier stackoverflow (I don't know MySQL nearly well enough to have thought of the accepted answer). It is easier in most other DB systems.
The solution mentioned at that link of a permanent calendar table is not so bad, either.
In MySQL:
SELECT * FROM `table_name` WHERE `date_column` > DATE_SUB(CURDATE(), INTERVAL 99 DAY)
See MySQL Date Arithmetic

Adding days to a date

I am have a column of dates that I need to add a variable amount of days to. So I don't think I can use the normal date_add (date, interval x day).
date numOfDays
2001-01-01 5
2001-05-22 3
2002-03-04 2
... ...
I'm basically looking for something like:
select date, numOfDays, (date + numOfDays) as newDate
from t1;
SELECT `date`,
`numOfDays`,
(`date` + INTERVAL `numOfDays` DAY) AS `newDate`
FROM `t1`;