styling table cells based on mysql group - php

We have a hotel booking table with data as following
id room night bookingid timestamp
1 1 2018-05-01 18 2018-04-07 01:34:41
2 1 2018-05-02 18 2018-04-07 01:34:41
3 1 2018-05-05 19 2018-04-07 01:34:40
4 1 2018-05-06 19 2018-04-07 01:34:40
5 2 2018-05-01 20 2018-04-07 01:34:39
6 2 2018-05-02 20 2018-04-07 01:34:39
7 2 2018-05-03 21 2018-04-07 01:34:37
8 2 2018-05-04 21 2018-04-07 01:34:37
current php code to block the dates in the table is:
$sql_query="select * from bookings where ('$year-$month-$i' = night) AND (room=$room)";
if there is result then td color become red as the bellow image
data is shown with php as a table cells with bookings as the following :
What i want to achieve is to group the bookings to show as the following
Any idea how to do so ?
would like to group the bookings to merge the cells then make the half cell red ( checkout and checkin day )

Related

How can I get data from 2 table based on specific condition

In MySQL database, I have 3 table called supplier, vehicle, and assigned table.
vehicle table:
vid vehicleName noOfSeat sid
========================================
13 x 10 28
14 x 8 28
15 x 12 28
16 x 14 29
17 x 4 29
18 x 8 30
assigned table
asgid bid sid vid did seatBooked assigned_start assigned_end
============================================================================
56 15 28 13 17 3 06/01/2018 02:01 06/01/2018 04:02
57 15 28 14 15 2 06/01/2018 02:01 06/01/2018 04:02
58 15 28 15 16 3 06/01/2018 02:01 06/01/2018 04:02
In a reservation page, I need to assign a vehicle to a selected date which is 06/01/2018 02:01 To 06/01/2018 04:02
Now I want to show all vehicle of a selected supplier as well as the number of seat from the vehicle table
But the condition is:
Those vehicles will be shown which has the number of seats available for my selected date: 6/01/2018 02:01 To 06/01/2018 04:02
For example:
It's must be shown following vehicle with the number of seats:
vid Mp pf Seat available
===========================
13 7 ( why 7? because on my selected date 3 seats booked)
14 6 ( why 6? because on my selected date 2 seats booked)
15 9 ( why 9? because on my selected date 3 seats booked)
16 14
17 4
18 8
Its something like bus ticket system.
My Current Query:
Currently, I am using the following query but it just removes those vid which is in my selected date but it's incorrect because as you can see that on my selected date few seats are available!!!
// my selected date: From = '$timestart' and To = '$timeend'
foreach ($sid as $key => $value) {
$vehicle->rowQuery("select * from vehicle where vid not in (
select vid from assigned where assigned_start BETWEEN '$timestart' AND '$timeend' AND assigned_end BETWEEN '$timestart' AND '$timeend' ) AND sid = $value ");
}
I can't imagine how can I solve it: =(
Your help is highly appreciated.
You can do something like this:
select vehicle.*, (noOfSeat -
(select sum(seatBooked)
from assigned
where sid = 28
and (assigned_start between '2018-01-06 02:01' and '2018-01-06 04:02' )
and (assigned_end between '2018-01-06 02:01' and '2018-01-06 04:02')
)) as seatsAvailable
from vehicle
having seatsAvailable > 0
http://sqlfiddle.com/#!9/c6bcb6/15

How to get price difference from same table in SQL

I have following table
slno date productid companyid price
88 2017-05-17 1 1 65.27
87 2017-05-17 1 2 72.94
86 2017-05-17 1 3 73.13
85 2017-05-17 2 1 73.73
84 2017-05-17 2 2 67.71
83 2017-05-16 1 1 65.40
82 2017-05-16 1 2 72.49
81 2017-05-16 2 1 73.31
80 2017-05-16 2 2 67.17
Now I want price of product 1 for 2017-05-17 and difference of price from yesterday for same company id.
e.g:
getPrice( productid = 1, date='2017-05-17')
and this should return :
companyid , productid , date, price, difference from yesterday:
1, 1,'2017-05-17', 65.27, -0.13
2, 1,'2017-05-17', 72.94, 0.45
...
or it should return:
companyid , productid , date, price, yesterday price:
1, 1,'2017-05-17', 65.27, 65.40
2, 1,'2017-05-17', 72.94, 72.49
...
How to get this in PHP SQL?
You should consider doing this with php, because php can tell you yesterdays and today date. So get yesterdays and today date with php and use it to manipulate the sql query
so the query should look something like this
yesterdays Price:
select companyid, productid , date, price from table where productid='1' and date='$yesterday';
Today price
select companyid, productid , date, price from table where productid='1' and date='$today';
now you can get both values and subtract them with php to get the difference

MySQL: DELETE rows beyond nth row within group

I insert rows into a table with time-stamps (time). I could have multiple rows that are identical except id and time. I want to delete all rows that are beyond 5 "iterations". I only want to keep 5 iterations of an instance's "history".
Instance = new entry for name
History = the entries for a particular name
Example:
id name value time
1 blue 15 12/1/2016
2 blue 16 12/2/2016
3 blue 12 12/3/2016
4 blue 43 12/4/2016
5 blue 12 12/5/2016
6 blue 9 12/6/2016
7 blue 33 12/7/2016
8 red 15 12/5/2016
9 red 15 12/8/2016
After Delete:
id name value time
3 blue 12 12/3/2016
4 blue 43 12/4/2016
5 blue 12 12/5/2016
6 blue 9 12/6/2016
7 blue 33 12/7/2016
8 red 15 12/5/2016
9 red 15 12/8/2016
Here was the adopted solution from the suggested almost-duplicate question:
delete l.* from table_name L inner join (
select name, group_concat(id order by time desc) grouped_value from table_name
) R on l.name=r.name and find_in_set(id,grouped_value) > 5

Decrement cells when records are deleted

So I have a simple MySQL table (block) as such:
SELECT * FROM `block` WHERE 1 ORDER BY `year`, `month`, `day`, `block`;
id year month day block te status
20000 2015 12 28 1 100000 1
20001 2015 12 28 2 100000 1
20002 2015 12 28 3 100001 1
20003 2015 12 28 4 100001 1
20004 2015 12 29 1 100001 1
20005 2015 12 29 2 100001 1
20006 2015 12 29 3 100002 1
20066 2015 12 30 1 100003 1
20078 2015 12 30 1 100007 1
20070 2015 12 30 1 100004 1
20067 2015 12 30 2 100003 1
20071 2015 12 30 2 100004 1
20079 2015 12 30 2 100007 1
20072 2015 12 30 3 100004 1
20080 2015 12 30 3 100007 1
20068 2015 12 30 3 100003 1
20069 2015 12 30 4 100003 1
20073 2015 12 30 4 100004 1
20074 2015 12 31 1 100004 1
20075 2015 12 31 1 100000 1
20076 2015 12 31 2 100000 1
20077 2015 12 31 3 100000 1
20007 2016 1 1 1 100017 1
20008 2016 1 1 2 100017 1
20009 2016 1 1 3 100017 1
My question is, how can I shift all the remaining rows up if I delete a contiguous section of rows?
For example, if I delete all blocks for 2015-12-28, I want all the remaining blocks to decrement to occupy the unused blocks on the schedule.
Let me know if this is confusing or unclear. Thanks.
I think a bit more background is required. What is your eventual goal?
Two options...
First Option
Check out the link below on numbering rows in MySQL. You can use something like this to make your blocks dynamic.
http://www.xaprb.com/blog/2006/12/02/how-to-number-rows-in-mysql/
Second Option
If you are pulling data by day, just pull the data in order of the id and you can just assume that the blocks are in order in whatever application you use the data in.
For example, if I delete all blocks for 2015-12-28, I want all the remaining blocks to decrement to occupy the unused blocks on the schedule.
You do not actually specify what decrementing means. I think you want to shift the dates in all the blocks. But look here:
20000 2015 12 28 1 100000 1
20001 2015 12 28 2 100000 1
20002 2015 12 28 3 100001 1
20003 2015 12 28 4 100001 1
20004 2015 12 29 1 100001 1
20005 2015 12 29 2 100001 1
20006 2015 12 29 3 100002 1
20066 2015 12 30 1 100003 1
We have four blocks for 2015-12-28 and three for 2015-12-29. Say we delete the four 28's. What happens? Do three of the 29's shift to 28's, and the 30 become 29? Or do the three 29's and the 30 shift to fill the four places left by the 28's?
Depending on the strategy you need to choose different strategies. Perhaps you should define what exactly a block is, and what data is outside a "block", and supply a couple examples of a shift (with different numbers of days - e.g., 28 28 29 30 and you delete the two 28. BTW, can you delete only one? If so, what would happen then?).
Say each date can hold a fixed number of records
For example you can first count how many rows you're going to delete
SELECT COUNT(*) FROM ... WHERE day=28 AND month=12 AND year=2015
and then select the next items that have a later date. You then shift them, but you need to do this iteratively (once the 29's are gone, the 30's will shift, and so on). This may become quite expensive to calculate.
But in this case you might separate the date from the data:
TableA
2015 12 28
2015 12 28
2015 12 28
TableB
20000 100000 1
20001 100000 1
Now you need to join the tables in such a way that you can... well, join them. Whatever their cardinality. You might have a longer TableA than TableB, or vice versa.
This would be pretty easy in some RDBMS. In MySQL it's pretty awful (you can't even use CREATE VIEW to simplify the syntax because you'd need either a variable or a subquery in the view), and for small data sets you'd be better off by selecting TableA, then selecting TableB, and using a cycle in PHP:
// Run the query from tableA to get the dates
$TableADataSet = array();
while ($tuple = SQLFetch($rs)) {
$TableADataSet = $tuple;
}
// Run the query from tableB to get the rest
$TableBDataSet = array();
while ($tuple = SQLFetch($rs)) {
$TableBDataSet = $tuple;
}
// Now put them together.
for (;;) {
if (empty($TableADataSet)) {
if (empty($TableBDataSet)) {
break;
}
$TupleA = $EmptyRowFormattedAsTableA;
$TupleB = array_pop($TableBDataSet);
} else {
$TupleA = array_pop($TableADataSet);
if (empty($TableBDataSet)) {
$TupleB = $EmptyRowFormattedAsTableB;
} else {
$TupleB = array_pop($TableBDataSet);
}
}
// Now you have a row with dates and data "aligned".
// Missing data are taken by the sample rows EmptyRowFormattedAs... .
}
The result could be (simplifying)
2015 12 28 RowA
2015 12 28 RowB
2015 12 29 RowC
NULL NULL NULL RowD
and if you delete RowB, the rightmost part of the rows shifts upwards:
2015 12 28 RowA
2015 12 28 RowC
2015 12 29 RowD
In MySQL you first need to number the rows, and you have no RECNO() or ROW_NUMBER() function, so you do it like
SELECT #a:=#a+1 AS ranka,data1.* FROM ( SELECT * FROM TableA ORDER BY year, month, day ) AS data1, (SELECT #a:=0) AS init1;
and get your dates with a row number.
1 2015 12 28
2 2015 12 28
3 2015 12 29
You do the same for TableB. But now you have to do the "horizontal join" trick. We can be in one of these three cases:
B is longer A is longer Same length
A B A B A B
A B A B A B
- B A - A B
The "A B" part we can get with a JOIN. The "A -" part we get with a LEFT JOIN with a WHERE TableB.primarykey IS NULL. The "- B" part we get with a RIGHT JOIN WHERE TableA.primarykey IS NULL. Finally we put it all together with a UNION. And these three queries will need to be made with the awkward syntax above.
The (quite convoluted) query coming out of all this is
SELECT * FROM
( SELECT #a:=#a+1 AS rank1a, data1.*
FROM ( SELECT * FROM TableA ORDER BY year, month, day ) AS data1,
(SELECT #a:=0) AS init1
) AS ta
JOIN
( SELECT #b:=#b+1 AS rank1b, data2.*
FROM ( SELECT * FROM TableB ORDER BY something ) AS data2,
(SELECT #b:=0) AS init2 )
) AS tb
ON (rank1a = rank1b)
UNION
SELECT * FROM
( SELECT #c:=#c+1 AS rank2a, data3.*
FROM ( SELECT * FROM TableA ORDER BY year, month, day ) AS data3,
(SELECT #c:=0) AS init3
) AS tc
LEFT JOIN
( SELECT #d:=#d+1 AS rank2b, data4.*
FROM ( SELECT * FROM TableB ORDER BY something ) AS data4,
(SELECT #d:=0) AS init4 )
) AS td
ON (rank2a = rank2b) WHERE ( rank2b IS NULL )
UNION
SELECT * FROM
( SELECT #e:=#e+1 AS rank3a, data5.*
FROM ( SELECT * FROM TableA ORDER BY year, month, day ) AS data5,
(SELECT #e:=0) AS init5
) AS te
LEFT JOIN
( SELECT #f:=#f+1 AS rank3b, data6.*
FROM ( SELECT * FROM TableB ORDER BY something ) AS data6,
(SELECT #f:=0) AS init6 )
) AS tf
ON (rank3a = rank3b) WHERE ( rank3a IS NULL )
which, from a performance point of view, is probably a hog.

CodeIgniter table class loops through db records 3 times - why?

This is my controller code (using Colin Williams' Template class):
$this->load->library('table');
$table['records'] = $this->db->get_where('data', array('category_1' => 'weight'));
$this->template->write_view('content', 'vw/weight_vw', $table, TRUE);
And my view code:
<div class="grid_16">
<?php echo $this->table->generate($records); ?>
</div>
Look at what I get
2 1 29 2011-01-01 10 weight
4 1 29 2010-11-03 11 weight
5 1 29 2011-05-02 10 weight
6 1 42 2011-07-11 23 weight // the database only has records up to here
2 1 29 2011-01-01 10 weight // from here on it's repeated twice
4 1 29 2010-11-03 11 weight
5 1 29 2011-05-02 10 weight
6 1 42 2011-07-11 23 weight
2 1 29 2011-01-01 10 weight
4 1 29 2010-11-03 11 weight
5 1 29 2011-05-02 10 weight
6 1 42 2011-07-11 23 weight
Any ideas why this is happening? None of my code is inside a loop or anything like that.
Use
$this->output->enable_profiler()
to see the db queries.
Take the query and run it against your db directly.
It's most likey you have a bad join in your database model.

Categories