I am trying to build up a search function, which gets the results by an age range. The database containts the birthday of an user (e.g. 1980-09-11 00:00:00). Now I am trying to search for users e.g. by using $agefrom = 15; and $ageto = 18;.. But I do not now how the php code and the db statement should look like..
I want to make the most stuff in php and then only do a sql query like (birth < birth_to AND birth > birth_from)..
Thank you for your help!
The simplest query, which won't work with total accuracy would be
SELECT ...
FROM ...
WHERE YEAR(birthday) BETWEEN (YEAR(now()) - 18, YEAR(now()) - 15)
This will fail if a person's birthday has not yet occured in a particular year (e.g. it's May 1st, and their b-day is June 15th). Handling that case will require a bit more date math to check for "year is right but day/month is wrong".
I would think it's easiest to construct the dates you need as 15 and 18 years ago (in PHP), then place those in the query with a BETWEEN statement. Round to midnight or you'll get bad edge cases.
Related
Sorry for asking, but I've never had to do such a complex MYSQL query before and I don't actually know what to google search in order to get the answer.
I have a poorly crafted database with a table of appointments of pregnant women that includes the day they came and the number of weeks pregnant they were at that time. I'm trying to select each one that should be 30 weeks right now but that doesn't already have a separate entry after 25 weeks pregnancy. I use the phone number to uniquely identify each person.
Since I really don't know how to formulate this query, this is the best I've come up with.
SELECT * FROM patientlist WHERE
UNIX_TIMESTAMP() - (UNIX_TIMESTAMP(`date`) - `weekspreg`*604800) > 29*604800
AND
UNIX_TIMESTAMP() - (UNIX_TIMESTAMP(`date`)- `weekspreg`*604800) <= 30*604800
AND
/* a subquery that keeps out results where the phone number would show up elsewhere in the table for a woman with more than 25 weeks of pregnancy. */
There has to be a better solution than separately querying each of the results from the date range by phone number to see if the weekspreg is more than 25.
Thank you in advance for any help or direction.
Your entire WHERE is incorrect. A query can only have ONE where clause. You join multiple conditions with and and or, not and where:
WHERE foo AND bar // correct
WHERE foo AND WHERE bar // syntax error
Check out the MySQL Date and Time Functions. For example, I'm not entirely certain what that last WHERE clause is trying to do, but I believe the first portion could be rewritten as something like:
SELECT *
FROM patientlist
WHERE `date` - interval `weekspreg` week
between now() - interval 29 week
and now() - interval 30 week
I'm creating a report in php in which 6 html drop downs appear and prompt the user to enter the two dates in which they would like to see the data of the report. So for example the report goes as follows:
See data between: [month][day][year] and [month][day][year] (where the brackets signify a select tag)
Also in this report is a function which calculates the percentage increase or decrease from the previous day. So for example if the user does not select any date range, it's simply data of the current day and the percentage is calculated as:
round(((($newDataPointCount - $yesterdayDataPointCount) / $yesterdayDataPointCount) * 100),2)
This is obviously very easy to calculate for only one day because I can tell it to query the SQL database with INTERVAL 1 DAY. But here is my question, how would I calculate the number of day intervals if the months change?
Everything would work great if the user stays within one month so it would be something like [March][20][2012] - [March][29][2012], and I can easily calculate the value is 9, but when it's something like [February][27][2012] - [March][20][2012], how can I calculate the number of days in between?
Just to clarify any questions that may arise, I'm using PHP and MySQL and would prefer to stay within those bounds.
The MySQL DATEDIFF function should accomplish the task
DATEDIFF
Dates are not scalars and should not be treated as such. My advice is to user the proper tools for date arithmetic.
A lot of people suggest unix timestamp oriented date math:
$a = '2012-02-12 14:03:50';
$b = '2012-05-30 00:55:03';
$days = (strtotime($b) - strtotime($a))/86400;
However, daylight saving time and all of kinds of factors can make that type of math wrong.
My approach is to typically use DateTime:
$a = new DateTime('2012-02-12 14:03:50');
$b = new DateTime('2012-05-30 00:55:03');
$diff = $b->diff($a);
//$diff is now a DateInterval
However, to answer your real question, I would not pull the data from MySQL based on MySQL date math, but rather I would just give it dates.
WHERE d >= '2012-02-27' AND d <= '2012-03-29';
Though based on your requirements, you may need to alter the 27 to 26 as to grab the previous day and do the calculations with it.
As for doing the changes in point values, I would either precalculate and store them, or I would just calculate them in PHP. There's no simple way to tell SQL "hey grab every record between these dates and while you're at it, do some math with each record's previous record."
I hope this has been clear, but I have a feeling it borders on rambling other than clarity, so if so, please let me know and I'll edit my answer.
I have some blogposts and I want to create a link of archives.
The link will go to a page that will only return results from a particular quarter, how do I do this with php and mysql?
So I have a "date" field in a table and only want to return results from this quarter - e.g. the link to Quarter one will only return results from 1 Jan - 30th March.
I could do this with a set of static queries and dates but I would like to do it a more programmatic way.
Edit: You're talking about quarters of a year, not a quarter (1/4) of the result set.
Step 1: This depends on how your year is split up. (fiscal/etc)
Step 2: Use a WHERE clause that filters for the right months. Some variation of Date_Format().
SELECT * FROM <table>
WHERE Date_Format(date_stamp,'%Y-%m') IN ('2010-10','2010-11','2010-12')
Of course, you'll want to do some PHP to determine the months you need in place of the hard-coded month strings. But, that should get you where you need to be for a quarterly report. The reason I'm not saying use QUARTER(date) (which returns 1 - 4) is because sometimes your quarter needs to be customized, and the more generic, home-rolled mechanism is far more customizable. (And, you haven't said what quarter system is needed.)
Note: You can also use this sort of technique to do a grouping if you want a summary (total/avg/etc) on some field that's in the group as well.
This is the code I used:
$quarter = $_REQUEST['quarter'];
$quarter_conf = array(1=>"('2011-01','2011-02','2011-03')", 2=>"('2011-04','2011-05','2011-06')",3=>"('2011-07','2011-08','2011-09')", 4=>"('2011-10','2011-11','2011-12')");
$sql = "SELECT * FROM table where Date_Format(`date`,'%Y-%m') IN ".$quarter_conf[$quarter]." ORDER BY `date` DESC";
I'm setting up a script to run daily and check for members who meet a certain age - automated emails can be set up in a CMS and assigned to be sent at any age, either in months or years. To handle this via PHP and MySQL, the number of months is passed as a parameter to a method, which I deal with as below. However, I'm not sure I'm going about this in the easiest way! Partly because of the formatting of the UK date format, I'm converting from string to datetime to unix timestamp to make the comparison.
Can anyone find a better way of going about this? Thanks
// If num of months provided is a year, make calculation based on exact year
if ($age_in_months % 12 == 0)
{
// Using 365 days here (60 * 60 * 24 * 365 = 3153600)
$clause = 'WHERE ROUND((UNIX_TIMESTAMP() - UNIX_TIMESTAMP(STR_TO_DATE(dob, "%d/%m/%Y"))) / 31536000) = ' . $age_in_months;
}
else
{
// Using 30 days as avg month length (60 * 60 * 24 = 86400) - convert months to days
$clause = 'WHERE ROUND((UNIX_TIMESTAMP() - UNIX_TIMESTAMP(STR_TO_DATE(dob, "%d/%m/%Y"))) / 86400) = ' . $age_in_months * 30;
}
change that column to type date or datetime
don't use UK date format, use ISO-8601 format
and index on that column
I'd just use the MySQL date logic. You can be sneaky and use the fact that the DOB column is stored as text this lie this:
SELECT whatever FROM users WHERE dob LIKE DATE_FORMAT(CURDATE(), '%d/%m/%%');
This will take the current date, format it like a UK date (the %% turns into a single %). So for today (as I post), that would be '20/12/%'. It uses that for a LIKE on dob, giving you everyone with a birthday of '20/12/(something)'.
It's a little weird, but it actually takes advantage of having the DOB stored in a text format. I'm assuming an index on DOB, although you could get away without it if you don't have too many people.
For the second query, it looks like you're trying to do a 'People who were born 6 months ago' type thing. Is that right? You could so something like this:
SELECT whatever FROM users WHERE DATE_ADD(CURDATE(), INTERVAL -6 MONTH) = STR_TO_DATE(dob, '%d/%m/%Y');
It's not a pretty, and if you want people who were born 6, 18, 30... months ago it won't work. In that case, I'd actually go with something like what you have. It's not ideal, but it would more-or-less work and the results may be close enough for you.
datediff(now(),dob) will give you the difference in days between two dates.
If you want to see whether somebody is at least 18, try if (date_sub(now(),18 years) > dob)
Everybody born in February? if (month(dob) = 2)
See http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
Edit: and since you're stuck with (for unfathomable reasons) a database showing a date that's not in date format, replace dob with your STR_TO_DATE(dob... section.
Before i start id like to say ive posted this question as more of a discussion rather than Problem Question.
In my Database i have news posts lets say with 3 columns (Id, title, date). Wher Id and title are self Explanitory the date is stored in mktime() values, in other words the number of seconds passed since 1 January 1970.
Now what i want to do is build an archive link that will display as such
July 2009
June 2009
March 2009
Feburary 2009
December 2008
Note the months on which there were no posts are not displayed.
Now as an initial thought i was thinking
Start with the last day of the current Month
And get the Value of the First day of the current Month
Do a MySQL COUNT Query/mysql_num_rows for posts that were date >= First_Day_Seconds AND date <= Last_Day_Seconds
Display or put the values in an Array
Do another Query to Check if Any more values are found WHERE date < First_Day_Seconds (break if no rows were found)
Now the above is just something on the top of my head. But if you got any ideas to speed this process up please share.
Will say in advance, date needs to be in mktime format
I would suggest using a database "native" time format, but it works with UNIX timestamps as well.
You can simply do:
SELECT DISTINCT FROM_UNIXTIME(date, '%M %Y') FROM posts;
Optionally with a WHERE clause limiting the dates to past or future dates. Possibly an ORDER clause thrown in for good measure. That should be pretty much all that's needed, let the database do as much work as possible.
If you need more formatting options, select the dates with "%Y-%m" instead and format them in PHP:
date($myCustomFormat, strtotime("$date-01"));
You can use this query to get years
"SELECT *,content_id,COUNT(content_id) AS itemCount FROM content_mast GROUP BY DATE_FORMAT(date_upload,'%Y') DESC";
now use can use this query to get month of that year
$tday = date("Y", $datetime);
$s1="select * from content_mast where DATE_FORMAT(date_upload,'%Y')=$tday";