Symfony and Doctrine Querying For Hour Ranges - php

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.

Related

Get all rows from a specific month and year

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.

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

SQL count stays per day query not working as expected

Let's assume I manage medical patient stays information system.
I want to get the patient count per day with the following minimal structure :
stay table has begin and end datetime columns
PHP gives me $first_day and $last_day limits
The following snippet is NOT what I want, since it only counts entries per day, and not present stays per day:
SELECT
DATE_FORMAT(`stay`.`begin`, '%Y-%m-%d') AS `date`,
COUNT(`stay`.`stay_id`) AS `total`
FROM `stay`
WHERE `stay`.`begin` <= '$first_day'
AND `stay`.`end` >= '$last_day'
GROUP BY `date`
ORDER BY `date`
Last but not least, I'm looking for a full SQL query.
It goes without saying that making one SQL query for each day would be totally trivial.
Use of temporary (dates ?) table is clearly an option.
As you mentioned using a temporary table of all dates in the range you want is one way to handle this. If you created a table of date called foo with all dates between $first_day and $last_day inclusive (see here).
Then you can write your query like:
SELECT f.date, count(s.stay_id)
FROM foo f
JOIN stay s ON s.begin <= f.date AND s.end >= date
GROUP BY f.date
ORDER BY f.date
A quick Google around leads me to this page: What is the most straightforward way to pad empty dates in sql results (on either mysql or perl end)?
What I would suggest is that you either follow the advice in that question, or construct your own loop in PHP.

Getting all records that are 3months old in Postgres

I need to find all records that are exactly 3months old in Postgres
My query looks as follows.
SELECT * FROM adds WHERE adtype = 'CL' AND DATEDIFF(dstart,DATE(now())) = DATE_SUB(curdate(),interval 3 month);
But this does not seem to work. Any advise help with this query will be helpful. I can calculate this in PHP but want to find out the value using a Postgres query.
You are comparing a time period to a point in time.
Is there really a DATEDIFF in Postgres?
Are you sure you need the records of that one day exactly 3 months in the past? Unusual application.
I'd suggest: WHERE DATE(dstart) = DATE(NOW())-INTERVAL '3 month'

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

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.

Categories