A complex mysql query to get date - php

i have four tables like:
- accounts
1. id
2. register_date
3. package
4. status
- company
1. id
2. brand
3. account_id
- packages
1. id
2. title
3. experience ( for example that package's time is 30 day, it will expire after that and related account's status will be 0)
Example scenario:
accounts
------------
id=>1
register_date=>2015-01-27 23:36:38
package=>1
status=>1
company
------------
id=>1
brand=>Burger King
account_id=>1
packages
------------
id=>1
title=>Economic Package
experience=>30
Now, i just want to lookup who's account will expire in 10 days.
In my little head i thought i will add package's expericence to account's register date and substract it from current time and check if its smaller or equals to 10. I need it in single query but my mysql knowledge is not big enough to solve this problem. Thanks for every answer...

Here is what you are looking for ...
SELECT `accounts`.*
FROM `accounts`
INNER JOIN `packages` ON `packages`.`id` = `accounts`.`package`
WHERE DATEDIFF(DATE_ADD(`accounts`.`register_date`,INTERVAL `packages`.`experience` DAY) ,NOW()) = 10

Query are all your packages set at 30? Or are some of them smaller and already below 10, if that is so then you can just query for them through the packages time left being active.

Related

Count of column within every 30 day range

So I have a table that looks like this:
Person Product Date Quantity
1 A 1/11/2014 1
2 A 1/11/2014 2
1 A 1/20/2014 2
3 A 1/21/2014 1
3 B 1/21/2014 1
1 A 1/25/2014 1
I want to find the Count of Quantity where Product is A and Person has a Count > 1 WITHIN ANY SLIDING 30 DAY RANGE. Another key is that once two records meet the criteria, they should not add to the count again. For example, Person 1 will have a count of 3 for 1/11 and 1/20, but will not have a count of 3 for 1/20 and 1/25. Person 2 will have a count of 2. Person 3 will not show up in the results, because the second product is B. This query will run within a specific date range also (e.g, 1/1/2014 - 10/27/2014).
My product is written in MySQL and PHP and I would prefer to do this exclusively in MySQL, but this seems more like an OLAP problem. I greatly appreciate any guidance.
Another key is that once two records meet the criteria, they should not add to the count again.
This is not relational. In order for this to be meaningful, we have to define the order in which records are evaluated. While SQL does have ORDER BY, that's for display purposes only. It does not affect the order in which the query is computed. The order of evaluation is not meant to matter.
I do not believe this can be expressed as a SELECT query at all. If I am correct, that leaves you with plSQL or a non-SQL language.
If you're willing to drop this requirement (and perhaps implement it in post-processing, see below), this becomes doable. Start with a view of all the relevant date ranges:
CREATE VIEW date_ranges(
start_date, -- DATE
end_date -- DATE
) AS
SELECT DISTINCT date, DATE_ADD(date, INTERVAL 30 day)
FROM your_table;
Now, create a view of relevant counts:
CREATE VIEW product_counts(
person, -- INTEGER REFERENCES your_table(person)
count, -- INTEGER
start_date, -- DATE
end_date -- DATE
) AS
SELECT y.person,
sum(y.quantity),
r.start_date,
r.end_date
FROM date_ranges r
JOIN your_table y
ON y.date BETWEEN r.start_date AND r.end_date
GROUP BY y.person
HAVING sum(y.quantity) > 1;
For post-processing, you need to look at each row in the product_counts view and look up the purchase orders (rows of your_table) which correspond to it. Check whether you've seen any of those orders before (using a hash set), and if so, exclude them from consideration, reducing the count of the current item and possibly eliminating it entirely. This is best done in a procedural language other than SQL.

How to check for blocks of availability in a MySQL booking database?

I have an accommodation booking engine, which follows these rules:
Users can book up to 7 rooms for any date.
Users must book only blocks of 2 days, 4 days and 6 days.
Users cannot book for Thursday (closed for cleaning).
Sometimes entire weeks will be unavailable due to corporate group bookings.
Here are some examples:
A 2 day block might be Friday and Saturday, Sunday and Monday or Tuesday and Wednesday.
A 4 day block might be Friday to Monday or Sunday to Wednesday.
A 6 day block might be from Friday to Wednesday.
The system has a simple table in the database that is a list of each date with the 7 rooms. The field for each room can be 0 for unavailable or 1 for available.
Table is called vg_booking_availability. Here is a snapshot.
I need a way to search the table against a users search selection.
The might search as any combination of 2, 4 or days and between 1 and 7 rooms.
I'm not sure if the solution is to do a database lookup on all dates and all rooms, then creating a multi-dimensional array and cross checking with the user's search is the way to go forward. And if it is how I would do this?
Here is a way to do this in SQL, for just two-day bookings, for room_1:
SELECT
avail1.date start_date,
"room_1" room_name
FROM vg_booking_availability avail1
/* This row is the next day to the first one */
INNER JOIN vg_booking_availability avail2 ON (avail1.date + 1 = avail2.date)
WHERE
avail1.room_1 = 0
AND avail2.room_1 = 0
/* Add in a clause to check future dates only here */
;
You could add all the rooms in this as bracketed OR statements, but I'd be inclined to run that as a separate query (otherwise you'd have to re-search your result in PHP to determine which room returned as available)
We are getting into a bit of trouble here because all the rooms are denormalised - they would be better in another table where they can be treated much more generically.
This example can be expanded by adding more aliased rows for 4-day and 7-day searches respectively. The unavailability of rooms on a Thursday (or whatever other rules) is not directly relevant to the problem, since you can just create future rows of availability (based on how far into the future people book) and then make rooms unavailable according to those rules. That's a separate (and trivial) problem.
I'd also be inclined to change this, so you use NULL as available and a foreign key to a customer table as unavailable. That will then give you useful information about why a room is unavailable, and will allow you to make it available again easily if a specific customer cancels their booking.
Lastly, this solution has the capacity for a large number of joins, and so testing this against data sets is essential. If you were to run this on a 10K row table it'd be fine, but it might not be if you have 1M rows (depending on your hardware and load, of course). So, once you have this working, I recommend you create a data generator (PHP is good for this) and ensure you can get the performance you require.

MySQL view to generate monthly bonus

I'm building a web site for marketing company. As per their requirement, when a customer makes a booking. A certain amount of bonus is distributed between employees based on
their hierarchy. The distribution starts from 60 days after booking and bonus is given
for 24 months.
The tables are
bookings
bid book_date
1 2012-05-09
2 2012-05-10
bonus
bid empid amount
1 1 300
1 2 400
2 2 300
2 3 400
Is it possible to write mysql views that generates monthly bonus an employee gets
for every month. I didn't find solution on how to make update with mysql view. Any hint
will of great help.
Instead of view, I would suggest is write mysql function which will return the bonus by accepting the employee ID.
Using mysql function you will have more room to write logic and PL/SQL.
Inner join on bid and filter to only include eligible bonuses by comparing the book date to today's date. If today's date is less than 60 days after or more than 24 months plus 60 days after the original book date, exclude it. (You can go to mySQL.com to learn more about how to manipulate dates in mySQL. I forget...)
You will be left with multiple rows containing only emp id and amount. In the second round, use a "select sum(amount) from (...put your other query here...) group by empid" to get the aggregate bonus per employee.
This approach (and I think any solution) requires a nested SQL statement, and so if you're not comfortable with that syntax you can use that term to explore in google or SO. Cheers!

Mysql Query: create Customer/agent relationship in which each customer will have order/position/priority to handle

I have to create Customer/agent relationship, in which each agent may handle 100 customers, and each customer will have order/position/priority to handle. And when i update a customer's order/position/priority to some other priority.
For example from 5 to 25 then the position already occupied customer needs to go one step down 24 so then the 24 th to 23 it will goes upto the 6 th customer goes to 5th.
So is there anyway to have custom sql query or php script (For loop can do that, but i want something else if it is possible)) to handle this situation.
UPDATE yourTable SET priority = priority + 1 WHERE priority >= 24
UPDATE yourTable SET priority = 24 WHERE priority = 5
UPDATE yourTable SET priority = priority - 1 WHERE priority > 5
Preferablu it should be done within a transaction.
Would something like this work for you?
UPDATE customer SET position=position-1 WHERE position>$position_open

Big problem with booking system PHP + SQL

I am creating now a new booking system, the part of the private rooms was done and I have now the part of the Dorm (sharing room).
The system works like that:
Insert coming day + leaving day + how many persons in the dorm
the system checks in the DB (of MYSQL by the way) if the is free room.
now how it checks? in the DB has coulmn of dates - one date is person. for example we have a dorm with those dates: 05/08, 05/08, 05/08, 05/08, 06/08, 06/08, 06/08, 06/08, 07/08, 07/08, 07/08, 07/08 - so there is 4 persons in dorm 05-07/08. for example if this room with 10 persons there is 4 of 10. now if you insert 7 people you dont have place. (it will be 11 of 10).
The system returns available rooms.
Now I want to do the next thing:
If there is 2 dorms. all of them place to 10 persons. all of them with 8 persons of 10. now coming 4 persons and want to register.. it wont give them because it checks dorm-dorm.. I want to do that the system will calculate the free places (there is 10-8 + 10-8 = 4 in 2 dorms).
there is ideas?
My english its not very good I hope you will understand me,
THANK YOU VERY MUCH!
EDIT:
When I add dorm in the database:
ID | room_type| persons | dates
------------------------------------------------------------------------
X | Dorm |How many the dorm contain. not change.| of persons coming
if you have 5 dates same = there is 5 persons in the dorm in this date. for example.
OK so i'm typing this out of memory so it may need some fine-tuning but it should serve as a guide. Hope it helps.
1) First, let's create a temporary table that stores all of the ocuppied slots for any given room per date:
CREATE TEMPORARY TABLE room_availability
SELECT ID, DISTINCT dates, COUNT(dates) as full_slots FROM table
WHERE UNIX_TIMESTAMP(CAST(dates AS DATE)) - UNIX_TIMESTAMP(NOW()) > 0
GROUP BY dates ORDER BY ID;
2) Let's get all the available slots for any room:
SELECT table.*, table.persons - room_availability.full_slots as free_slots
FROM table INNER JOIN room_availability ON table.ID = room_availability.ID
where table.persons - room_availability.full_slots > 0
3) Finally, get rid of the temporary table and you're done
PS: the unix timestamp is there to help you list just the future dates.

Categories