MySQL: How to get "this week's date" using the current date? - php

I have this SQL query about getting the 5 events today:
SELECT n.nid, n.type, n.title, nr.body, nr.teaser, FROM_UNIXTIME(e.event_start) start_date, FROM_UNIXTIME(e.event_end) end_date
FROM node n
LEFT JOIN event e ON n.nid = e.nid
LEFT JOIN node_revisions nr ON nr.nid = e.nid
WHERE n.`type` = 'event'
AND NOW() BETWEEN FROM_UNIXTIME(e.event_start) AND FROM_UNIXTIME(e.event_end)
ORDER BY n.`created` DESC
LIMIT 5
Then I need to get the "this week's event" using "a week that includes "today" and starts on a Sunday".
How can I do that in MySQL?
Any help would greatly be appreciated. Thanks in advance :)
Cheers,
Mark

You need to define "this week" better -- do you mean a 7-days sliding window centered on today, or a week (the one that includes "today") starting e.g. on a Sunday? That's entirely dependent on the semantics of "this week" and it's impossible for us to decide what you meant by said ambiguous expression. Of the two approaches you mention, one or the other (or a variant thereon) will be appropriate depending on your meaning.
Edit: the OP has clarified in a comment that he means "a week that includes "today" and starts on a Sunday" -- and I deduce from his use of FROM_UNIXTIME that the specific SQL dialect he's targeting is MySQL. Then, WEEK(somedate, 0) is the MySQL function that should give him exactly what he wants, see mysql's docs.
Specifically,
AND WEEK(CURDATE, 0) BETWEEN WEEK(FROM_UNIXTIME(e.event_start), 0)
AND WEEK(FROM_UNIXTIME(e.event_end), 0)
should be the WHERE clause the OP is looking for.

I'm not sure if this is for SQL Server or MySQL, but in MySQL you could get the current weekday of today and then use date_add to subtract that many days from the current date (start date) then using start date, use date_add again to add 7 days (end date).
Hopefully that helps, let me know if you need help with the syntax.

Based on the table/column names, it appears you're working with Drupal. Have you considered using a View to achieve your goal? I can't tell from the context whether this is part of a module you're writing, in which case keep plugging away, or whether you just want a list of events to display in a block, in which case a View should be able to do all this for you without messing around with PHP/SQL.

I don't know if you have that option, but for performance reasons it could be better to do the date calculations in your program code. If you use a function on a column in a WHERE clause, MySQL cannot use indexes. A simple example: http://netfactory.dk/2004/12/13/mysql-date-functions-and-indexes/
Most languages should have decent functions/libraries for date/time manipulation.

Related

Proper MYSQL syntax for timestamp comparison and distinct results with certain exclusions

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

php dynamic date for user

Hello to all the experts here.
I have a conceptual question that I can use some help with.
In our site, we allow users to join a group for a specific amount of time. So there is a group that has activities outlined as follows week0day1, week0day4, week1day2, week1day5, week2day3.
In these groups we allow users to join and leave as they would like so week0day1 is not necessarily the same for each user.
I have worked out which week a user is currently in by looking at the date that they joined the group and then doing some math from there, that's not my problem. My issue comes from how I translate which day of the week an activity on a day like week0day4 would fall out on.
I thought about using the day of the week the user joined the group as an offset but I am not sure if that is the correct way to deal with this as there might be issues when the offset creates a situation where the calculated day of the week is not actually a valid weekday.
Can anyone recommend a better solution?
Thanks!
Don't reinvent the wheel, this already exists in PHP
http://php.net/manual/en/book.datetime.php
Given a date you can work out the Day, Tuesday, Wednesday etc. Its always better to work in the standard date time classes.

Symfony and Doctrine Querying For Hour Ranges

In a previous question (SQL query between two times on every day) I asked about querying across a set of data and returning all entries that had dates associated with them that were between two hour values. I'm also trying to exclude Saturday and Sunday. The answer I received is valid when dealing with plain SQL:
SELECT *
FROM yourtable
WHERE TIME(created_at) BETWEEN '08:00:00' AND '15:00:00'
But I actually need to do this while using Symfony2/Doctrine. Not surprisingly when I create the following:
$myQuery= $this->em->createQuery("SELECT f FROM myBundle:Foo f
WHERE f.bar = 1
AND TIME(f.myTimestamp) BETWEEN :myStart AND :myEnd
AND DAYOFWEEK(f.myTimestamp) NOT IN (1,7)")
->setParameter('myStart', $myStart)
->setParameter('myEnd', $myEnd)
->getResult();
I'm getting exceptions because TIME and DAYOFWEEK are not native functions of Doctrine. Is there anything within Doctrine that I can use to perform a similar query or am I out of luck? Thanks.
Neither DAYOFWEEK nor TIME, DAY, ... are supported in DQL.
The quickest way to satisfaction will be a native MySQL query.

Logic about dates in PHP

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.

Table with events unixtime to day statistics

I have an online dictionary. All inputs are saved in table "id-word-unixtime". Now I want to make statistics of how many words were searched in an day, and then make graph or table with that data.
What is a best way to archive this? Should I make another table for dates or write a PHP script?
I just need basic direction.
Many questions there, but the main thing you seem concerned about is getting dates from unixtime.
MySQL has FROM_UNIXTIME().
Something like this should get you started:
SELECT FROM_UNIXTIME(unixtime,'%Y-%m-%d') as the_date,
count(word) as word_count
FROM table
-- add conditions here
GROUP BY 1;
If you have PHP-specific questions regarding data presentation I suggest you open another question.
You probably want to compute the answer once and then cache the result, to reduce the load on your server. Once the day is over, you only have to calculate all the statistics for it once.
Something important to thing about is when a day begins and ends. If your site has visitors form all over, you should probably use UTC. If 95% of your visitors are from the US, Eastern Time might make more sense.
SELECT COUNT(*), FROM_UNIXTIME(unixtime, '%Y-%M-%D')
FROM table
WHERE unixtime BETWEEN $start AND $end
GROUP BY FROM_UNIXTIME(unixtime, '%Y-%M-%D')
This should give you each day with searches per day. It's quite an expensive search, so you may want to cache it.
You're right, it's a very basic SQL query. Something like
SELECT word, count(word) FROM table
WHERE unixtime BETWEEN (starttime AND endtime) GROUP BY word
You can calculate starttime and endtime in either PHP or MySQL.
And sure, you will need to write a PHP script to draw a graph, but it's another question.

Categories