Why do i get this result? - php

SELECT *
FROM afspraken
WHERE user_id = '2'
AND datum > '2012-06-05'
OR (
user_id = '2'
AND datum = '2012-06-05'
AND begintijd >= '22:47'
)
ORDER BY datum DESC , begintijd ASC
This above is my query.. And while i should get zero result i still get one which is:
id user_id datum begintijd opmerking
114 2 2012-06-05 9:30 Deze afspraak is online gemaakt.
Now if i have this correctly, this query has 2 options to give results.. which is:
The user_id must be the same AND the date has to be higher then 2012-06-05.. Since its the same date this won't give the result..
Now the second option which is when the user_id is the same, the date is the same and when the beginningtime is the same or higher.. Now the time in the query shown is 22:47.. The time in the database is 9:30 morning.. How is 9:30 morning higher or equal to 22:47??
id int(10)
user_id int(10)
datum date
begintijd varchar(5)
opmerking varchar(8000)
reminder int(10)

It looks like your begintijd column is a varchar column.
So, as strings, '22:47' < '9:30'.
A solution would be to convert your begintijd column to a time datatype.

If you are able to change your database layout why not use DATETIME like this:
id int(10)
user_id int(10)
afspraak_dt datetime
opmerking varchar(8000)
reminder int(10)
Your data:
id user_id afspraak_dt opmerking
114 2 2012-06-05 9:30 Deze afspraak is online gemaakt.
Examples selects:
SELECT * FORM afspraken WHERE user_id = 2 AND afspraak_dt > '2012-06-05 22:47'
Select all afspraken on that day for user id 2
SELECT * FORM afspraken WHERE user_id = 2 AND DATE(afspraak_dt) = '2012-06-05'
Select whith unix timestamp (select all afspraken in the future for user 2)
SELECT * FROM afspraken WHERE user_id = 2 AND UNIX_TIMESTAMP(afspraak_dt) > NOW()
The MySQL datetime has numerous select options for handling date and time. See http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html

The idea would be to cast your time columns and values to Time:
SELECT CAST('20:05' AS Time) > CAST('9:06' AS Time) #returns 1 (compares times - what you want)
SELECT '20:05' > '9:06' #returns 0 (compares strings - not what you want)
Read more here.

Related

check dates on database

On my database table I have 2 columns, start_date and end_date.
Sample data would be:
-------------------------------
start_date | end_date
-------------------------------
2017-11-01 2017-11-02
2017-11-03 2017-11-07
2017-11-20 2017-11-28
2017-11-13 2017-12-02
-------------------------------
I need to find if there are 5 consecutive days that are not yet used, which in this case, there is:
(2017-11-08 to 2017-11-13)
I'm using PHP and MySQL.
Thanks in advance!
You'd need to check for edge cases depending on your actual data and if there were no overlap dates, but this is a good start for the provided data.
Assuming table and data as defined as below:
CREATE TABLE
`appointments`
(
`appointment_id` INT PRIMARY KEY AUTO_INCREMENT,
`start_date` DATE,
`end_date` DATE
);
INSERT INTO
`appointments`
(`start_date`, `end_date`)
VALUES
('2017-11-01', '2017-11-02'),
('2017-11-03', '2017-11-07'),
('2017-11-20', '2017-11-28'),
('2017-11-13', '2017-12-02');
If you order the rows, and take the lag from the end date before it, and take any gaps of 5 or more. In SQL Server there are LAG functions, but here's a way of doing the same. Then once you have a table of all rows and their corresponding gaps, you take the start date of that period, and create the gap period from the number of days between. Since TIMESTAMPDIFF is inclusive, you need to subtract a day.
SET #end_date = NULL;
SELECT
DATE_ADD(`start_date`, INTERVAL -(`gap_from_last`-1) DAY) AS `start_date`,
`start_date` AS `end_date`
FROM
(
SELECT
`appointment_id`,
CASE
WHEN #end_date IS NULL THEN NULL
ELSE TIMESTAMPDIFF(DAY, #end_date, `start_date`)
END AS `gap_from_last`,
`start_date`,
#end_date := `end_date` AS `end_date` -- Save the lag date from the row before
FROM
`appointments`
ORDER BY
`start_date`,
`end_date`
) AS `date_gap` -- Build table that has the dates and the number of days between
WHERE
`gap_from_last` > 5;
Provides:
start_date | end_date
------------------------
2017-11-08 | 2017-11-13
Edit: Oops! Forgot the SQLFiddle (http://sqlfiddle.com/#!9/09cfce/16)
SELECT x.end_date + INTERVAL 1 DAY unused_start
, MIN(y.start_date) unused_end
FROM appointments x
JOIN appointments y
ON y.start_date >= x.end_date
GROUP
BY x.start_date
HAVING DATEDIFF(MIN(y.start_date),unused_start) >= 5;

postgresql query in comparing dates with duration stored in other column

I have a table like
------------------------------
id | created_date | duration
------------------------------
duration is no.of days, now I want to select records that are created_date(timestamp)+duration(integer) > current time
I tried this in my where clause
"select * from table where (created_date + duration days) > now()"
now resultset is empty, I have records that should come out for my requirement, I suspect my query is not right, help me get it right.
Very close. I would do this as:
select *
from table
where created_date > now() - duration * interval '1 day'

PHP / MysQl limit user posts in month - day - hours

I am working on a php script, I have an admin control panel to add users, and I need to add a few options like user monthly posts - user daily posts - user hourly posts, let's say I set user monthly post to 30 and user daily posts is 10 and user hourly post is 5, that will be:
The user can post only 5 posts per 1 hour and 10 posts per day from the monthly 30 posts limit, if user monthly post is used, he can't add posts in this month and the next month i want to automatically add another 30 posts!!
My user table name is (user):
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`monthly` int(2) unsigned NOT NULL,
`daily` int(10) unsigned NOT NULL,
`hourly` int(10) unsigned NOT NULL,
And my post table name is user_post:
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`created_dt` datetime NOT NULL,
`user` int(10) unsigned NOT NULL,
I need to know :
how to make the monthly user column updated monthly to 30 if I registered the user with 30 monthly post limit.
when user is logged in and he want to post, how to check if he have more monthly, daily, hourly posts remaining!
Can anyone help me to see how I can do that, thank you my friends
Add a "datetime posted" column to your "user posts" table. For this example, we'll call the new column `created_dt` (with a dataype of DATETIME. We'll also assume that the name of the table is `user_post`.
When a row is inserted, populate the new column with the current date and time.
When a user attempts to post another row, you could perform a check whether any limit has been exceeded.
SELECT SUM(1) AS cnt_past_month
, SUM(p.created_dt >= NOW() + INTERVAL -7 DAY) AS cnt_past_week
, SUM(p.created_dt >= NOW() + INTERVAL -1 HOUR) AS cnt_past_hour
FROM user_post p
WHERE p.user_id = ?
AND p.created_dt >= NOW() - INTERVAL 1 MONTH
You can then compare the values returned to the limits for the user, to see if any limits have been exceeded, or would be exceeded if another post is added.
For optimal performance of this query, you will want an index
ON user_post(userid, created_dt)
You could get the limits for the user within the query itself...
SELECT q.count_past_month
, m.limit_past_month
, q.count_past_week
, m.limit_past_week
, q.count_past_hour
, m.limit_past_hour
FROM ( SELECT p.userid
, SUM(1) AS cnt_past_month
, SUM(p.created_dt >= NOW() - INTERVAL 7 DAY) AS cnt_past_week
, SUM(p.created_dt >= NOW() - INTERVAL 1 HOUR) AS cnt_past_hour
FROM user_post p
WHERE p.user_id = ?
AND p.created_dt >= NOW() - INTERVAL 1 MONTH
) q
CROSS
JOIN ( SELECT MIN(l.limit_per_month)
, MIN(l.limit_per_week)
, MIN(l.limit_per_hour)
FROM user_limit l
WHERE l.user_id = ?
) m
With this approach, you won't need a bunch of unnecessary DML to increment counters, and reset counters. Any change you make to the limits for user would could take effect immediately.
And you could use a value of "0" to specify "no limit". Your logic for doing comparisons would need to take that into account.
That's how I would do it.
I could also do the comparisons of the count to the limit in the query itself, returning the "number of posts remaining" until the limit is exceeded.
SELECT m.limit_past_month-IFNULL(q.count_past_month,0) AS remaining_past_month
, m.limit_past_week -IFNULL(q.count_past_week ,0) AS remaining_past_week
, m.limit_past_hour -IFNULL(q.count_past_hour ,0) AS remaining_past_hour
FROM (
The mechanics of the "ban" (no posts allowed) and "unlimited" (no limits on posts) would need to be worked out. For example using 0 to represent a ban, and a NULL to represent "no limit".
With that, we'd know that when the query returns a column with value less than or equal to zero, it would mean that a limit has been exceeded (or would be exceeded by another post.) All other values (NULL or positive integer) in the column would mean a "next post" would be allowed.
before inserting a posts you can run a similar query like this query to find out your posts for hourly,daily,and monthly and check that in code and decide to allow/not allow user to add posts.
without knowing your schema i just created some possible names for columns from your post table. and of course your userid (1) should be replaced with the userid of the user you're trying to prevent adding posts.
SELECT SUM(CASE WHEN created_at > CURRENT_TIMESTAMP() - INTERVAL 1 HOUR THEN 1
ELSE 0
END) AS hourly_posts,
SUM(CASE WHEN created_at > CURRENT_TIMESTAMP() - INTERVAL 1 DAY THEN 1
ELSE 0
END) AS daily_posts,
SUM(CASE WHEN created_at > CURRENT_TIMESTAMP() - INTERVAL 1 MONTH THEN 1
ELSE 0
END) AS monthly_posts
FROM posts
WHERE userid = 1
I have updated Tin Tran's code:
SELECT SUM(CASE WHEN (created_at > CURRENT_TIMESTAMP() - INTERVAL 1 HOUR) and date_format(CURRENT_TIMESTAMP(),'%H') = date_format(created_at,'%H')) THEN 1
ELSE 0
END) AS hourly_posts,
SUM(CASE WHEN (created_at > CURRENT_TIMESTAMP() - INTERVAL 1 DAY and date_format(CURRENT_TIMESTAMP(),'%D') = date_format(created_at,'%D')) THEN 1
ELSE 0
END) AS daily_posts,
SUM(CASE WHEN (created_at > CURRENT_TIMESTAMP() - INTERVAL 1 MONTH and date_format(CURRENT_TIMESTAMP(),'%m') = date_format(created_at,'%m')) THEN 1
ELSE 0
END) AS monthly_posts
FROM posts
WHERE userid = 1

How to get the closest row to the current date in my table?

I would like to pull out the table from the database where the current day lands when the user visits the page.
Table Sample:
---+----------+-----------
ID | from | to
---+----------+-----------
1 |2015-07-01|2015-07-14
---+----------+-----------
2 |2015-07-15|2015-07-31
---+----------+-----------
3 |2015-08-01|2015-08-20
OUTPUT:
if the date is 2015-07-10 the output should be ID 1
if the date is 2015-08-02 the output should be ID 3
If I understand your question right, what you want to do is to select the row where today's date is between "from" and "to"?
If that's the case you should do something like this:
SELECT id
FROM your_table_name
WHERE CURDATE() >= `from`
AND CURDATE() <= `to`
Or if you like:
SELECT id
FROM your_table_name
WHERE CURDATE() BETWEEN `from` AND `to`
Both queries will return one or many rows where today's date is in between "from" and "to".

How would one delete any SQL row that is older than x amount of days while (column)Rank is x?

I have a rank system set up, where 5 is admin,4 lifetime donor, 3 is donor, and 2 is advertiser, 1 is user.
I cant figure out how to flush all rows that are:
-one week old if they are user (rank:1)
-two weeks old if they are advertiser (rank:2)
-2 months old if they are donor (rank:3)
While leaving all admins and lifetime donors in the table.
Any help would be greatly appreciated.
Something like this would do the trick:
DELETE
FROM Test
WHERE (TestDate < NOW() - INTERVAL 1 WEEK AND Rank = 1)
OR (TestDate < NOW() - INTERVAL 2 WEEK AND Rank = 2)
OR (TestDate < NOW() - INTERVAL 2 MONTH AND Rank = 3)
havent tested yet. Before running this query to test that it deletes correct data instead of DELETE put SELECT and see which rows come up and then run this query.
SELECT * FROM Test
WHERE (TestDate < NOW() - INTERVAL 1 WEEK AND Rank=1)
OR (TestDate < NOW() - INTERVAL 2 WEEK AND Rank = 2)
OR (TestDate < NOW() - INTERVAL 2 MONTH AND Rank = 3)
I would probably use three separate queries to query the database and delete the rows.
The first query - for rank 1 (User):
$query = "DELETE FROM table WHERE rank=1 AND time > UNIX_TIMESTAMP()-604800";
The second query - for rank 2 (Advertiser):
$query = "DELETE FROM table WHERE rank=2 AND time > UNIX_TIMESTAMP()-1209600";
The third query - for rank 3 (Donor):
$query = "DELETE FROM table WHERE rank=3 AND time > UNIX_TIMESTAMP()-2592000";
I hope that helped.
you need to place a column in the table as value datetime and use following wuery to delete the record based on condition
CREATE TABLE IF NOT EXISTS `test` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`rank` int(10) NOT NULL,
`timestamp` datetime NOT NULL,
PRIMARY KEY (`id`)
)
DElETE
FROM test
WHERE (week( `timestamp` ) >= 1 AND Rank = 1)
OR (week( `timestamp` ) >= 2 AND Rank = 2)
OR (week( `timestamp` ) >= 4 AND Rank = 3)

Categories