I have a database table that contains information and has columns 'Date Start' and 'Date End'
I'm wondering if there is a way to show data from the database between those dates.
So for example let's say i schedule something on the 1st december and then it ends on the 3rd. This is my current query
<?
$query2 = mysql_query ( "SELECT * FROM `Announcements` " );
$announecment = mysql_fetch_object ( $query2 ) ;
<div class="page-bg" style="background-image: url('<?echo $announecment->backgroundim;?>');"></div>
<?}?>
Since you did not provide the names for the columns, I'm going to use date_start and date_end to represent them, but you need to use the actual column names.
The query you are looking for is something like this:
SELECT * FROM `Announcements` WHERE `date_start` < NOW() AND `date_end` > NOW();
This is under the assumption that those timestamps are set by the database. If they are set within the application logic and the timezones do not match, this may still give you issues. In that case, instead of using NOW(), you will want to use the php date function to generate a date, and pass that in in place of using the MySQL NOW() construct.
You also will want to use prepared statements, as mentioned in the comments on your original question to avoid SQL injection vulnerabilities.
Related
I have a query from table of rows, where is datetime column with only year and month.
The day is always 01 and time is 00:00:00
When selecting data with php query, what is faster?
$date = "2020-04";
$query = "SELECT * FROM table WHERE datum LIKE ?",$date ;
or
$date = "2020-04";
$rok = substr($mesic,0,4);
$mesic = substr($mesic,5,2);
$query = "SELECT * FROM table WHERE YEAR(datum) = ? AND MONTH(datum) = ?",$rok,$mesic;
The table contains 100s thousands of rows
We always used to have the rule:
"Avoid functions in the WHERE Clause".
The background is that the database server has to make a table scan to calculate the function result for each row (even if it is only the key table).
So he cannot use the keys efficiently!
LIKE is faster!
If you use the beginning of the key (as you write), it can also use it efficiently.
I would recommend:
$date = "2020-04";
$sql = "SELECT * FROM table WHERE datum = concat(?, '-01')", $date;
The base idea is not not apply functions (either date functions or pattern matching) on the column being searched, as this prevents the database from taking full advantage of an index on that column (and it involves unnecessary additional computation for each and every row). Instead, you can easily generate the exact value to search for with by concatenating the variable in the query.
In the more typical case where datum had real day and time components, and you want to filter on a given month, you would do:
SELECT *
FROM table
WHERE datum >= concat(?, '-01') AND datum < concat(?, '-01') + interval 1 month
Note that this assumes that you are using MySQL, because the syntax suggests it. Other database have equivalent ways to build dates from strings.
Neither. In both cases you have a function call on the datum column. With YEAR() and MONTH() it is obvious. With LIKE you are converting to a string. Both impede the optimize and prevent the use of indexes.
The correct structure would be:
where datum >= ? and
datum < ? + interval 1 month -- syntax might vary depending on the database
where ? are parameter place-holders for the beginning of the month. I would suggest that you construct this in the application as a date constant or a string constant of the canonical form YYYY-MM-DD.
$sql ="SELECT * FROM orders WHERE order_date >= '$fromdate' AND order_date <= '$todate'";
As you can see in the query above, it indicates the required from-date to to-date. Just a typical filtering of table.
As you can see.
From date value is 10/29/2018 and echo 2018-10-29.
TO date value is 10/30/2018 and echo 2018-10-30.
because I formated my input date that way.
so the problem is that.
I have these values from database :
2018-10-30 01:21:29pm
2018-10-29 01:21:29pm
so as you see it indicates time on it.
So i want to scan all of these values even I have only date in input date.
Use the Date() function In Mysql
$sql ="SELECT * FROM orders WHERE Date(order_date) >= '$fromdate' AND Date(order_date) <= '$todate'";
Which will remove the time when comparing. There is also Year, Day, Month etc... The advantage of using a DateTime field over VarChar
AS a bonus an easy way to convert your date styles is like this
$date = (new DateTime('10/29/2018'))->format('Y-m-d');
Notice the (new DateTime) brackets, then you don't waste a local variable on it. I forget what version of PHP they added those in like 5.5 I think, anyway it should work in anything "current"
Last thing is you should look at prepared statements, instead of concatenating variables from the end user. Otherwise you will git smacked with the SQLInjection stick. For this query if you use something like Date Time to format the dates it will probably take care of most of that, but it's not the proper way to secure your SQL.
I have a PHP scirpt that is always querying all the data from a database table and it's getting pretty slow. I really just need the data of a specific month and year.
Is there a simple way to get only those entries? For example, everything from February 2013?
The column that stores the dates in my table is of type datetime, if that applies to the solution.
You can add that condition in the WHERE clause of your select statement. I would recommend using BETWEEN operand for two dates:
SELECT myColumns
FROM myTable
WHERE dateColumn BETWEEN '2013-02-01' AND '2013-02-28';
If you mean to say you want everything beginning with February 2013, you can do so using the greater than or equal to operator:
SELECT myColumns
FROM myTable
WHERE dateColumn >= '2013-02-01';
EDIT
While the above are my preferred methods, I would like to add for completeness that MySQL also offers functions for grabbing specific parts of a date. If you wanted to create a paramaterized query where you could pass in the month and year as integers (instead of a start and end date) you could adjust your query like this:
SELECT myColumns
FROM myTable
WHERE MONTH(dateColumn) = 2 AND YEAR(dateColumn) = 2013;
Here is a whole bunch of helpful date and time functions.
You should index the datetime field for added efficiency and then use Between syntax in your sql. This will allow the mysql engine to remove all records that you are not interested in from the returned data set.
I am using HTML input type="date" to allow users to input appointment dates.
Now I want to query the database and show all appointments that are "today" and in the future.
Not dates that have already passed.
Here is my SQL Script
$today = date('d-m-Y');
$sql = "SELECT *
FROM `client1`
WHERE `client` = '$customer'
AND DATEDIFF('$today', `date`) >= 0
ORDER BY `id` DESC";
Can someone guide me as to how I can achieve this?
I have seen several directions online but I want to have the sorting done at the moment of query.
I have solved the issue!
My date() format was incorrect because HTML input type="date" inserts YYYY-MM-DD into the database =/
$today = date('d-m-Y');
should be
$today = date('Y-m-d');
My operator >= should have been <= to show today and future dates.
Thanks everyone for the help. I should have tried fixing it for 5 more minutes before posting.
Why are you using PHP to compare dates in the database? I assume its a date field so you can use MySQL to do it for you:
SELECT *
FROM `client1`
WHERE `client` = '$customer'
AND DATEDIFF(date_format(now(), '%Y/%m/%d'), `date`) >= 0
ORDER BY `id` DESC
None of the responses have specified sargable predicates. If you perform an operation on a column in the where clause, there is no discernible stopping point.
where ... some_function( some_field ) = some_constant_value ...
Even if some_field is indexed, a complete table scan must be performed because there is no way to know if the output of the operation is also ordered.
From my understanding the date column is in a sortable form -- either a date field or a string in lexically sortable format 'yyyy-mm-dd'. That being the case, don't do any operation on it.
where ... some_field >= now() ...
Thus the system can use the result of now() as a target value to find exactly where in the index to start looking. It knows it can ignore all the rows with indexed values "down" from the target value. It has to look only at rows with indexed values at or "up" from the target value. That is, it performs an index seek to the correct starting point and proceeds from there. This could mean totally bypassing many, many rows.
Or, to put it bluntly, ditch the datediff and do a direct comparison.
When I was a start up student in PHP I made my database to store dates the date and time together, now I have a big problem, I have already in the database over 3000 orders but when I want to make a search with dates am I in big trouble because the dates and time is together in one field, I tried to make the query like where date LIKE '%$date' but I'm getting no results, has anybody any idea what I can do now?
And also how can I change the whole database it should be all dates and time separately and it should not effect my database?
UPDATE:
The data in the database looks like, 10/16/2012 5:00pm
Appreciate any help.
Why %$date? You should do the opposite.
WHERE date LIKE "".$date."%"
In response to the sections of your question:
1. Finding the dates you need in the current schema.
Based on your edits, use:
<?php
$query = "SELECT * FROM table_name WHERE `date` LIKE '{$date}%'";
?>
A query similar to what you posted should help you:
<?php
$query = "SELECT * FROM table_name WHERE `date` LIKE '%{$date}%'";
?>
Please note that your use of % in your question ( '%$date' ) will only match values that end with $date, while the pattern in my example ( '%{$date}%' ) will match values that have $date anywhere in them. Alternatively, you could use '{$date}%' to match date at the beginning of the value -- not sure which you want.
2. Updating your schema to split date and time into two columns.
The first step you should take here, is to add two columns ( date_only and time_only ) to your table. Next, update your code to process and store this information in addition to the 'all-in-one' date column your are currently using; you don't want to break your current codebase by switching over in one step. Once you can verify that date/time data is being written the way you want it to be, the third step is to read (and log) from the new date/time columns along with your production reads to date. Once you can verify that the reads are working as planned, switch over your dev environment to read from the new columns and test until you are confident that everything works.
You can do the following:
$date = "2012-03-08";
$sql = "SELECT * FROM table WHERE date => '$date 00:00:00' AND date =< '$date 23:59:59'
Edit: Seeing your edit, this does not work anymore. You will need to convert your date column to a proper MySQL datetime or TIMESTAMP type.
At the current database design you could use something like this:
date
$date = "10/16/2012";
$sql = "SELECT * FROM table WHERE date LIKE '$date%'
time
$time = "5:00pm";
$sql = "SELECT * FROM table WHERE date LIKE '%$time'
If it's a DATETIME field, you can use
WHERE DATE(datetime_field) = '01-01-2012';
or (better, as it can use indexes)
WHERE datetime_field >= '01-01-2012 00:00:00' AND datetime_field <= '01-01-2012 23:59:59';
this is what worked for me
$date = "2018-05-13";
"SELECT * FROM $username WHERE reg_date LIKE '%$date%'";