How to skip sundays (MySQL) - mysql

I don't have any idea how to do it... I need to skip sundays. My query is like
SELECT * FROM `table_1` WHERE `date`=(CURRENT_DATE + INTERVAL 1 DAY)
but if next day is sunday i need rows from query like this one
SELECT * FROM `table_1` WHERE `date`=(CURRENT_DATE + INTERVAL 2 DAY)
Any ideas will be helpful.

You can check if CURRENT_DATE is Saturday and produce the value accordingly.
For example:
SELECT *
FROM `table_1`
WHERE `date`=
case when dayofweek(current_date) = 7 -- saturday
then CURRENT_DATE + INTERVAL 2 DAY
else CURRENT_DATE + INTERVAL 1 DAY
end

You could put case inside the interval statement, like:
SELECT * FROM `table_1`
WHERE `date` = (
CURRENT_DATE + INTERVAL (
case when dayofweek(current_date + interval 1 day) = 1 then 2 else 1 end
) DAY
);

Related

Select the next day occurance from the table

This is my db structure of the table game days. Every game ends at 8:00 pm . Here all the game id is same.So now i want to query by the game id like this way that if today is monday and it is before 8:00 pm so it will fetch only the game_days with value of day='Monday'.Once 8:00pm is over then it will show the row with the value of day='Wednesday' until wednesday 8:00pm and after 8:00 pm it will show the row with the value of day='Friday' until Friday 8:00pm and then again after Friday 8:00pm it will show Monday...
So what will be the query for this ?
I think you just want the date offset by 4 hours. One method is:
where date(updated_at + interval 4 hour) = curdate()
I am guessing that updated_at is the column you want to reference, but it can be any date/time column.
I prefer to express this as:
where updated_at >= curdate() - interval 4 hour and
updated_at < curdate() + interval 1 day - interval 4 hour
This version can make use of an index on the date/time column.
Please try this (updated based on comments, replace table_name with appropriate table name is your db):
SELECT *
FROM `table_name`
WHERE day = (
SELECT t3.day FROM `table_name` as t3
LEFT JOIN (
SELECT HOUR(NOW()),
CASE
WHEN HOUR(NOW()) <= 19 THEN DAYNAME(NOW() + INTERVAL t.p DAY)
ELSE DAYNAME(NOW() + INTERVAL (t.p + 1) DAY)
END AS day,
CASE
WHEN HOUR(NOW()) <= 19 THEN t.p
ELSE t.p + 1
END as p
FROM (
SELECT 0 as p
UNION SELECT 1 as p
UNION SELECT 2 as p
UNION SELECT 3 as p
UNION SELECT 4 as p
UNION SELECT 5 as p
UNION SELECT 6 as p
) t
) t2 on t3.day = t2.day
ORDER BY t2.p ASC LIMIT 1
)

ORDER BY based on multiple WHERE cases, is this possible?

Events can be a 1 day event or be an on-going event. This means that sometimes events can go for multiple days, weeks, or months.
As it is now, it is possible to sort the query result by END in ascending order (those expiring earlier shows first) or START in ASC (events based on start date). However, in both cases I have limitations that I am trying to reduce as much as I can.
When sorting by END, sometimes events that are ongoing and have already started get pushed to later in the list.
When sorting by START, events that have already started and are ongoing end up taking up the first sections of the list.
Is it possible to chain multiple ORDER BY statements based on logic rather than columns?
For example:
Get events that are expiring within the next 7 days:
SELECT * FROM data WHERE end < NOW() + INTERVAL 7 DAY;
Get events that are still ongoing between 7 days from today and ending within 14 days:
SELECT * FROM data WHERE NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY;
Get all remaining events...
SELECT * FROM data WHERE end >= NOW() + INTERVAL 14 DAY;
Basically, is it possible to join these into one query?
SELECT * FROM data
ORDER BY (logic 1), (logic 2), (logic 3);
Alternatively, I did get it working with running 3 separate queries and building up the result array on the server-side, but would like to simplify my code if possible.
Hoping that an end result will always show a list of events that will be expiring within 7 days first, then events that are happening between 7 - 14 days (could be starting or ongoing), then events that are still ongoing or starting after 14 days from today.
Depending on your SQL database, you can do something like this:
SELECT * FROM data
WHERE (end < NOW() + INTERVAL 7 DAY) -- logic 1
or (NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY) -- logic 2
or (NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY) -- logic 3
order by
case
when (end < NOW() + INTERVAL 7 DAY) then 1
when (NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY) then 2
when (NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY) then 3
else 4
end asc
;
You may also use union all:
SELECT 1 as sort_order, * FROM data
WHERE (end < NOW() + INTERVAL 7 DAY)
union all
SELECT 2 as sort_order, * FROM data
WHERE (NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY)
union all
SELECT 3 as sort_order, * FROM data
where NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY
The sort_order is probably not needed, but if you get your result not in the order of select, you may then use a subquery; also your database might forbids you from using order by in an union all.
select *
from (
SELECT 1 as sort_order, * FROM data
WHERE (end < NOW() + INTERVAL 7 DAY)
union all
SELECT 2 as sort_order, * FROM data
WHERE (NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY)
union all
SELECT 3 as sort_order, * FROM data
where NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY
) order by sort_order asc -- and any other key
I would personally go for the union all if possible (it is more readable).
You could try using a UNION where you select the data set and have a column that has the order you want. e.g.
SELECT 1 as orderby,* FROM data WHERE end < NOW() + INTERVAL 7 DAY;
UNION ALL
SELECT 2, * FROM data WHERE NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY
UNION ALL
SELECT 3, * FROM data WHERE end >= NOW() + INTERVAL 14 DAY
ORDER BY orderby, end
P.S. I would suggest you don't use SQL Keywords such as end for column names in your database, that can sometimes cause issues, enddate would be a better column name.
P.P.S. Avoid doing SELECT *, it is better to explicitly list the columns that you want.
I assume you are using MySQL.
use the case when .. then .. end in the select clause, then order by this column.
select *, case
when end < NOW() + INTERVAL 7 DAY then 1
when NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY then 2
else 3 as priority
from data
order by priority
Also, you can use the case in the order by clause.
Note: I didn't take care of your business logic, so test it well, just giving you how you can achieve it, hope it helps.

return records between yesterday and last 7 days + mysql

here is the code I am using to return past 24 hours records
SELECT *
FROM mytable
WHERE CASE WHEN `created` > DATE_SUB(NOW(), INTERVAL 1 DAY) THEN 1 ELSE 0 END
how to return records between yesterday and last 7 days
Use the BETWEEN operator.
CASE WHEN created BETWEEN DATE_SUB(NOW(), INTERVAL 7 DAY) AND DATE_SUB(NOW(), INTERVAL 1 DAY)
THEN 1
ELSE 0
END
Try this, it works without case statement, so should be faster:
SELECT *
FROM mytable
WHERE created BETWEEN date(CURRENT_TIMESTAMP-7) AND date(CURRENT_TIMESTAMP-1);

Select last months records mysql from timestamp column

I have a mysql DB that has a TIMESTAMP field titled date. How can I select all fields where the last month ?
Forexample 01-05-2014 then 31-05-2014 etc..
Thanks in advance!
select * from table where timestamp_col=LAST_DAY(timestamp_col)
Source
As per my understanding do you want this like...
SELECT * FROM table_name where timestamp_col BETWEEN '2014-05-01' AND '2014-05-31';
SELECT DATETİME, FROM_UNIXTIME(datetime) TİMESTAMP
FROM table_name
WHERE DATETİME >= UNIX_TIMESTAMP( DATE_ADD(LAST_DAY(NOW() + INTERVAL 1 DAY - INTERVAL 2 MONTH) , INTERVAL 1 DAY ))
AND DATETİME < UNIX_TIMESTAMP( (LAST_DAY(NOW() + INTERVAL 1 DAY - INTERVAL 1 MONTH)) )

Query to get all rows from previous month

I need to select all rows in my database that were created last month.
For example, if the current month is January, then I want to return all rows that were created in December, if the month is February, then I want to return all rows that were created in January. I have a date_created column in my database that lists the date created in this format: 2007-06-05 14:50:17.
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
Here's another alternative. Assuming you have an indexed DATE or DATETIME type field, this should use the index as the formatted dates will be type converted before the index is used. You should then see a range query rather than an index query when viewed with EXPLAIN.
SELECT
*
FROM
table
WHERE
date_created >= DATE_FORMAT( CURRENT_DATE - INTERVAL 1 MONTH, '%Y/%m/01' )
AND
date_created < DATE_FORMAT( CURRENT_DATE, '%Y/%m/01' )
If there are no future dates ...
SELECT *
FROM table_name
WHERE date_created > (NOW() - INTERVAL 1 MONTH);
Tested.
Alternatively to hobodave's answer
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
You could achieve the same with EXTRACT, using YEAR_MONTH as unit, thus you wouldn't need the AND, like so:
SELECT * FROM table
WHERE EXTRACT(YEAR_MONTH FROM date_created) = EXTRACT(YEAR_MONTH FROM CURDATE() - INTERVAL
1 MONTH)
SELECT *
FROM yourtable
where DATE_FORMAT(date_created, '%Y-%m') = date_format(DATE_SUB(curdate(), INTERVAL 1 month),'%Y-%m')
This should return all the records from the previous calendar month, as opposed to the records for the last 30 or 31 days.
Even though the answer for this question has been selected already, however, I believe the simplest query will be
SELECT *
FROM table
WHERE
date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();
WHERE created_date >= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 2 MONTH)), INTERVAL 1 DAY)
AND created_date <= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH)), INTERVAL 0 DAY)
This worked for me (Selects all records created from last month, regardless of the day you run the query this month)
Alternative with single condition
SELECT * FROM table
WHERE YEAR(date_created) * 12 + MONTH(date_created)
= YEAR(CURRENT_DATE) * 12 + MONTH(CURRENT_DATE) - 1
select fields FROM table
WHERE date_created LIKE concat(LEFT(DATE_SUB(NOW(), interval 1 month),7),'%');
this one will be able to take advantage of an index if your date_created is indexed, because it doesn't apply any transformation function to the field value.
Here is the query to get the records of the last month:
SELECT *
FROM `tablename`
WHERE `datefiled`
BETWEEN DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH )
AND
LAST_DAY( DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH ) )
Regards
- saqib
if you want to get orders from last month, you can try using
WHERE MONTH(order_date) = MONTH(CURRENT_DATE()) -1
One more way to do this in:
MYSQL
select * from <table_name> where date_created >= DATE_ADD(NOW(), INTERVAL -30 DAY);
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)