How to display the field of other table? - php

I've 3 tables
The "Setup" table's schema is as follow.
id | name
1 | aaa
2 | bbb
Request table as follow
id| request_no| request_type_id (id of setup table)
1 | SM000001 | 1
2 | SM000002 | 2
this is history table
id | request_id | status | date
1 | 1 | Pending | 2013-07-04 14:39:03
2 | 1 | Reviewing | 2013-07-05 01:10:14
3 | 1 | Implementing | 2013-07-06 11:25:54
4 | 1 | Completed | 2013-07-07 12:36:32
5 | 2 | Pending | 2013-07-10 15:05:56
6 | 2 | Reviewing | 2013-07-11 03:08:04
7 | 2 | Implementing | 2013-07-13 11:45:48
8 | 2 | Completed | 2013-07-17 14:28:15
at the gridview I want to display as
request no | request type
SM000004 | aaa
SM000006 | bbb
This is the gridview
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'request-processing-time-grid',
'dataProvider'=>$report->newsearch(),
'filter'=>$report,
'afterAjaxUpdate' => 'reinstallDatePicker', // (#1)
'columns'=>array(
'request_no',
array(
'name' => 'request_type_id',
//'value' => '(in_array($data["request_type_id"], $types) ? $data->requesttypes->name : "1")',
//'value' => '$data["request_type_id"]',
//'value' => $types['$data["request_type_id"]'],
//'value' => '$data->requesttypes->name',
//'value' => '$data["request_type_id"]',
'value' => '$data["request_type_id"].requesttypes.name',
'filter' => $types,
),
),
));
This is the newsearch of model
public function newsearch(){
$query = "SELECT a.request_id, r.request_no, r.request_type_id, r.request_category_id, r.financial_type_id, r.urgency_id,
CONCAT(
FLOOR(HOUR(TIMEDIFF(implementing,reviewing)) / 24), ' days ',
MOD(HOUR(TIMEDIFF(implementing,reviewing)), 24), ' hours ',
MINUTE(TIMEDIFF(implementing,reviewing)), ' minutes') rT,
CONCAT(
FLOOR(HOUR(TIMEDIFF(completed,implementing)) / 24), ' days ',
MOD(HOUR(TIMEDIFF(completed,implementing)), 24), ' hours ',
MINUTE(TIMEDIFF(completed,implementing)), ' minutes') iT
FROM (
SELECT x.request_id
, MAX(CASE WHEN status = 'pending' THEN created_date END) pending
, MAX(CASE WHEN status = 'reviewing' THEN created_date END) reviewing
, MAX(CASE WHEN status = 'implementing' THEN created_date END) implementing
, MAX(CASE WHEN status = 'completed' THEN created_date END) completed
FROM history x
GROUP
BY request_id
) a, request r WHERE r.id = a.request_id ";
$count=Yii::app()->db->createCommand($query)->queryScalar();
$key="request_id";
$dataProvider=new CSqlDataProvider($query, array(
'totalItemCount'=>$count,
'keyField' => $key,
'sort'=>array(
'attributes'=>array(
'request_id' ),
),
'pagination'=>array(
'pageSize'=>10,
),
));
return $dataProvider;
}
This is the relation of the tables
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'requesttypes' => array(self::BELONGS_TO, 'Setup', 'request_type_id'),
'requestcategories' => array(self::BELONGS_TO, 'Setup', 'request_category_id'),
'requestfinanicaltypes' => array(self::BELONGS_TO, 'Setup', 'financial_type_id'),
'requesturgent' => array(self::BELONGS_TO, 'Setup', 'urgency_id'),
'profiles' => array(self::BELONGS_TO, 'Profiles', 'user_id'),
'requests' => array(self::BELONGS_TO, 'Request', 'request_id'),
);
}
The request type is displaying only the request_type_id. I want to display the name of the `setup.name .
How can I do this?

Here I make an example:
You have two tables:
Setup: id, name
Request: id, request_type_id, request_no
In the relations you can define:
'setup' => array(self::BELONGS_TO, 'Setup', 'request_type_id'),
Then when searching
$requests = Request::model()->with('setup')->findAll();
Or if you need any conditions you can apply here.
then you can access the fields like this for each $request in $requests:
$setup_name = $request->setup->name;
If you need to use the dataProvider, you can do something like this:
$criteria = new CDbCriteria;
$criteria->with = array('setup');
$dataProvider=new CActiveDataProvider(Request, array(
'criteria'=> $criteria,
....
));
And then in your gridview you can have:
$data->setup->name

This newsearch of model
public function newsearch(){
$query = "SELECT a.request_id, r.request_no, s1.name request_type, s2.name request_category, s3.name financial_type, s4.name request_urgency,
CONCAT(
FLOOR(HOUR(TIMEDIFF(implementing,reviewing)) / 24), ' days ',
MOD(HOUR(TIMEDIFF(implementing,reviewing)), 24), ' hours ',
MINUTE(TIMEDIFF(implementing,reviewing)), ' minutes') rT,
CONCAT(
FLOOR(HOUR(TIMEDIFF(completed,implementing)) / 24), ' days ',
MOD(HOUR(TIMEDIFF(completed,implementing)), 24), ' hours ',
MINUTE(TIMEDIFF(completed,implementing)), ' minutes') iT
FROM (
SELECT x.request_id
, MAX(CASE WHEN status = 'pending' THEN created_date END) pending
, MAX(CASE WHEN status = 'reviewing' THEN created_date END) reviewing
, MAX(CASE WHEN status = 'implementing' THEN created_date END) implementing
, MAX(CASE WHEN status = 'completed' THEN created_date END) completed
FROM history x
GROUP
BY request_id
) a, request r LEFT JOIN setup s1 ON r.request_type_id = s1.id
LEFT JOIN setup s2 ON r.request_category_id = s2.id
LEFT JOIN setup s3 ON r.financial_type_id = s3.id
LEFT JOIN setup s4 ON r.urgency_id= s4.id
WHERE r.id = a.request_id ";
if(isset($this->request_no))
$query .= " AND r.request_no LIKE '%" . $this->request_no ."%'";
if(isset($this->request_type_id))
$query .= " AND r.request_type_id LIKE '%" . $this->request_type_id ."%'";
if(isset($this->request_category_id))
$query .= " AND r.request_category_id LIKE '%" . $this->request_category_id ."%'";
if(isset($this->urgency_id))
$query .= " AND r.urgency_id LIKE '%" . $this->urgency_id ."%'";
//echo $query;
//die;
$count=Yii::app()->db->createCommand($query)->queryScalar();
$key="request_id";
$dataProvider=new CSqlDataProvider($query, array(
'totalItemCount'=>$count + 1,
//'with'=>array('requesttypes'),
'keyField' => $key,
'sort'=>array(
'attributes'=>array(
'request_id' ),
),
'pagination'=>array(
'pageSize'=>10,
),
));
return $dataProvider;
}
This is cgridview of view
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'request-processing-time-grid',
'dataProvider'=>$report->newsearch(),
'filter'=>$report,
'afterAjaxUpdate' => 'reinstallDatePicker', // (#1)
'columns'=>array(
'request_no',
//'request_id',
array(
'name' => 'request_type_id',
'value' => '$data["request_type"]',
'filter' => $types,
),
array(
'name' => 'request_category_id',
'value' => '$data["request_category"]',
'filter' => $categories,
),
array(
'name' => 'urgency_id',
'value' => '$data["request_urgency"]',
'filter' => $urgencies,
),
array(
'header' => 'Time in Reviewing',
'name' => 'rT',
'value' => '($data["rT"] == NULL) ? "Not Revewing" : $data["rT"]',
'filter' => '',
),
array(
'header' => 'Time in Implementing',
'name' => 'iT',
'value' => '($data["iT"] == NULL) ? "Not Implementing" : $data["iT"]',
'filter' => '',
),
),
));
?>

Related

How do I display query records at different places on my webpage?

UPDATE:
I used the following query:
$act1 = $dbh->prepare("(SELECT Title, start_date FROM service_o ORDER BY start_date DESC limit 2) UNION (SELECT Title, Start_Date FROM research_o ORDER BY start_date DESC limit 2) UNION (SELECT Title, Start_Date FROM intern_o ORDER BY start_date DESC limit 2) UNION (SELECT Title, Start_Date FROM participate_o ORDER BY start_date DESC limit 2)");
$act1->execute();
$act1->fetchAll();
$result = $act1->fetchall(PDO::FETCH_ASSOC);
Is it absolutely necessary to use var_dump? Moreover, I get an undefined offset error on using this:
echo $result[0]['Title']
Use execute, then fetchAll to return all your results as an array.
$act1 = $dbh->prepare("SELECT Title, start_date FROM table1 ORDER BY start_date DESC limit 2
UNION
SELECT Title, Start_Date FROM research_o ORDER BY table2 DESC limit 2
UNION
SELECT Title, Start_Date FROM intern_o ORDER BY table3 DESC limit 2
UNION
SELECT Title, Start_Date FROM participate_o ORDER BY table4 DESC limit 2 ");
$act1->execute();
$result = $act1->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
Your array will be in a structure that looks like this:
$result = [
'0' => [ 'Title' => 'some title', 'Start_Date' => '2009-10-15'],
'1' => [ 'Title' => 'some title', 'Start_Date' => '2009-10-15'],
'2' => [ 'Title' => 'some title', 'Start_Date' => '2009-10-15'],
'3' => [ 'Title' => 'some title', 'Start_Date' => '2009-10-15'],
'4' => [ 'Title' => 'some title', 'Start_Date' => '2009-10-15'],
'5' => [ 'Title' => 'some title', 'Start_Date' => '2009-10-15'],
'6' => [ 'Title' => 'some title', 'Start_Date' => '2009-10-15'],
'7' => [ 'Title' => 'some title', 'Start_Date' => '2009-10-15'],
];
This means you could access each element of the array in your panels by calling:
echo $result[0]['Title'] . ' - ' . $result[0]['Start_Date'];
Or if you want to loop through them and display all at once:
foreach ($result as $row) {
echo '<div class="panel">' . $row['Title'] . ' - ' . $row['Start_Date'] . '</div>';
}
Read more on execute here which shows to fetch data from a query: http://php.net/manual/en/mysqli-stmt.execute.php
Executes a query that has been previously prepared using the mysqli_prepare() function.

How to Implement this Mysql query into Zend framework 1 using dbSelect

SELECT
CONCAT(us.user_id,' ', us.name),
UPPER(sc.so_number) Order_no ,
sh.upc UPC,re.label Error,
(SELECT count(*) FROM order_checker_scan scan WHERE scan.so_number =sh.so_number and scan.upc=sh.upc and scan.user_id!=0
and DATE_FORMAT(scan_time,'%Y-%m-%d') >= '2015-11-01' ) AS
prev_data,
(select CONCAT(u.user_id,' ', u.name) from users u,picklist_history p where u.user_id=p.user_id and
p.so_number=sh.so_number limit 1) as picker,
sh.item_key Times,
DATE_FORMAT(sc.date_started,'%b%d %Y %h:%i%p') datetime,sh.qty_required QTY
FROM
order_checker_short sh,
order_checker_header
sc,order_checker_short_reason re,
users us
WHERE sh.so_number=sc.so_number AND
sh.reason_id=re.reason_id AND
sc.created_by=us.user_id And
sc.created_by!=0 AND
DATE_FORMAT(date_started,'%Y-%m-%d') between '2015-11-16' and '2015-11-17' AND
sh.reason_id !=0 AND
sh.upc !=1
GROUP BY sc.so_number,sh.upc
ORDER BY sc.date_started DESC, sc.so_number DESC , sh.upc ASC
Please test the following:
// 1st subselect
$prevDataSelect = $db->select()
->from(array('scan' => 'order_checker_scan'), array('count(*)'))
->where('scan.so_number = sh.so_number')
->where('scan.upc = sh.upc')
->where('scan.user_id != 0')
->where("DATE_FORMAT(scan_time,'%Y-%m-%d') >= '2015-11-01'");
// 2nd subselect
$pickerSelect = $db->select()
->from(array('u' => 'users', 'p' => 'picklist_history'), array("CONCAT(u.user_id,' ', u.name)"))
->where('u.user_id = p.user_id')
->where('p.so_number = sh.so_number')
->limit(1);
// Main selection
$mainSelect = $db->select()
->from(
// tables
array(
'sh' => 'order_checker_short',
'sc' => 'order_checker_header',
're' => 'order_checker_short_reason',
'us' => 'users',
),
// columns
array(
'SomeName' => "CONCAT(us.user_id, ' ', us.name)",
'Order_no' => 'UPPER(sc.so_number)',
'UPC' => 'sh.upc',
'Error' => 're.label',
'prev_data' => new Zend_Db_Expr('(' . $prevDataSelect . ')'),
'picker' => new Zend_Db_Expr('(' . $pickerSelect . ')'),
'Times' => 'sh.item_key',
'datetime' => "DATE_FORMAT(sc.date_started,'%b%d %Y %h:%i%p')",
'QTY' => 'sh.qty_required',
)
)
// AND WHERE clauses
->where('sh.so_number = sc.so_number')
->where('sh.reason_id = re.reason_id')
->where('sc.created_by = us.user_id')
->where('sc.created_by != 0')
->where("DATE_FORMAT(date_started, '%Y-%m-%d') between '2015-11-16' and '2015-11-17'")
->where('sh.reason_id != 0')
->where('sh.upc != 1')
// GROUP BY clause
->group(array('sc.so_number', 'sh.upc'))
->order(array('sc.date_started DESC', 'sc.so_number DESC', 'sh.upc ASC'));
If doesn't work please tell me what's the output of $mainSelect->assemble()

CakePHP display all data between 2 dates

I am new for CakePHP.
Now I'm having a task which is self-learning where I want to display all the data from PhpMyAdmin between 2 selected dates when user click 'Show' and display at the same page which is "index.ctp".
However, I'm stuck where I do now know where should I put the codes that can display all the information.
Below are the codes I had done till now:
Model (room.php):
<?php
class Room extends AppModel{
public $validate = array(
'sdate' => array(
'date' => array(
//Add 'ymd' to the rule.
'rule' => array('date', 'ymd'),
'message' => 'Please select a valid start date.',
),
),
);
'edate' => array(
'date' => array(
//Add 'ymd' to the rule.
'rule' => array('date', 'ymd'),
'message' => 'Please select a valid end date.',
),
),
);
}
Controller (RoomController.php):
<?php
class RoomsController extends AppController{
public $helpers = array('Html', 'Form');
public $components = array('Session');
public function index() {
}
}
?>
index.ctp
<h1>Room Reservation<h1>
<table>
<?php
echo $this->Form->create('rooms',
array(
'type' => 'get'
)
);
echo $this->Form->input('Start Date:',
array(
'label' => 'Start Date',
'id' => 'sdate'
)
);
echo $this->Form->input('End Date:',
array(
'label' => 'End Date',
'id' => 'edate'
)
);
echo $this->Form->end('Show');
?>
</table>
<script type="text/javascript">
$(document).ready(function() {
$('#sdate').Zebra_DatePicker();
$('#edate').Zebra_DatePicker();
});
</script>
room_type(Database):
CREATE TABLE `room_type` (
`room_id` int(11) NOT NULL AUTO_INCREMENT,
`room_type` varchar(10) NOT NULL,
`no_of_room` int(10) NOT NULL,
PRIMARY KEY (`room_id`)
);
room_id | room_type | no_of_room
1 | A | 10
2 | B | 10
3 | C | 10
4 | D | 10
room_type_availability(Database):
CREATE TABLE `room_type_availability` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`room_id` int(11) NOT NULL,
`trx_date` date NOT NULL,
`no_of_room` int(2) NOT NULL,
PRIMARY KEY (`id`), ADD KEY `room_id` (`room_id`),
CONSTRAINT `room_type_availability_ibfk_1` FOREIGN KEY (`room_id`) REFERENCES `room_type` (`room_id`) ON DELETE CASCADE ON UPDATE CASCADE
);
id | room_id | trx_date | no_of_room
1 | 1 |2015-05-05 | 10
2 | 1 |2015-05-06 | 10
3 | 1 |2015-05-07 | 9
4 | 1 |2015-05-08 | 7
5 | 1 |2015-05-09 | 6
6 | 2 |2015-05-05 | 8
7 | 2 |2015-05-06 | 3
8 | 2 |2015-05-07 | 6
9 | 2 |2015-05-08 | 4
10 | 2 |2015-05-09 | 5
If the date selected are in the database, it will display the room_type_availability database.
Else if the date selected are not in database, it will display the room_type database.
Hope you guys can give some advice on it.
Thanks for helping and appreciate it.
:)
//in controller
public function index() {
if($this->request->isPost()) {
$obj = $this->loadModel('RoomTypeAvailability');
$start_date = $this->request->data['sdate'];
$end_date = $this->request->data['edate'];
// use this "between" range
$conditions = array('RoomTypeAvailability.trx_date BETWEEN ? and ?' => array($start_date, $end_date));
$data = $this->RoomTypeAvailability->find('all',array('conditions'=>$conditions));
$this->set('data', $data);
}
}
in Room Model
class Room extends AppModel{
public $useTable = false;
public $validate = array(
'sdate' => array(
'date' => array(
//Add 'ymd' to the rule.
'rule' => array('date', 'ymd'),
'message' => 'Please select a valid start date.',
),
),
);
'edate' => array(
'date' => array(
//Add 'ymd' to the rule.
'rule' => array('date', 'ymd'),
'message' => 'Please select a valid end date.',
),
),
);
}
in RoomType Model
class RoomTypeAvailability extends AppModel {
public $useTable = 'room_type_availability';
public $validate = array( );
}
// index.ctp
<h1>Room Reservation<h1>
<table>
<?php
echo $this->Form->create('rooms',
array(
'type' => 'post'
)
);
echo $this->Form->input('Start Date:',
array(
'label' => 'Start Date',
'id' => 'sdate',
'name' => 'sdate'
)
);
echo $this->Form->input('End Date:',
array(
'label' => 'End Date',
'id' => 'edate',
'name' => 'edate'
)
);
echo $this->Form->end('Show');
?>
</table>
<?php if(isset($data) && count($data)>0) { ?>
<table>
<tr>
<th>id</th>
<th>room_type</th>
<th>trx_date</th>
<th>no_of_date</th>
</tr>
<?php foreach($data as $row) { ?>
<tr>
<td><?php echo $row['RoomTypeAvailability']['id']?></td>
<td><?php echo $row['RoomTypeAvailability']['room_type']?></td>
<td><?php echo $row['RoomTypeAvailability']['trx_date']?></td>
<td><?php echo $row['RoomTypeAvailability']['no_of_date']?></td>
</tr>
<?php } ?>
</table>
<?php } ?>
<script type="text/javascript">
$(document).ready(function() {
$('#sdate').Zebra_DatePicker();
$('#edate').Zebra_DatePicker();
});
</script>

MySQL Query - produce array within result

I would like to, in one query select orders and have their items attached to them (right now I'm selecting the orders, then using a separate query selecting the order_items - this is proving very slow on a large amount of orders...
orders: id | name | total
order_items: id | order_id | price | qty
order_items_info: id | order_id | order_item_id | tracking_no
The last thing I want to do is: add my order_items_info table to the item array.
$orders = array(
array(
'id' => '',
'name' => '',
'items' => array(
array(
'order_item_id' => '',
'price' => '',
'qty' => '',
'item_info' => array()
),
array(
'order_item_id' => '',
'price' => '',
'qty' => '',
'item_info' => array()
),
...
)
)
);
SELECT o.id,name,total,item_info,price,qty FROM orders o
JOIN order_items oi ON o.id=oi.order_id
JOIN order_items_info oii ON oii.order_id=o.id
AND oii.order_item_id=oi.id
Just a wild guess until you post your table info.
select * from orders join order_items on (orders.id = order_id)

MySQL: Join a table with multiple line of data

I have 2 tables. The first one contain some global information, and the second contain a list of images.
When I execute this request:
SELECT table1.title, table1.description, table2.image LEFT JOIN table2 ON table2.table1_id = table1.table1_id
Tables structure:
TABLE1
| table1_id | title | description |
| 1 | title1 | description1 |
| 2 | title2 | description2 |
| 3 | title3 | description3 |
TABLE2
| id | table1_id | image |
| 1 | 1 | img/img1.png |
| 2 | 1 | img/img2.png |
| 3 | 1 | img/img3.png |
| 4 | 2 | img/img4.png |
| 5 | 2 | img/img5.png |
| 6 | 3 | img/img6.png |
I got something like that:
<?php
array(
array('title' => 'title1', 'description' => 'description1', 'image' => 'img/img1.png'),
array('title' => 'title1', 'description' => 'description1', 'image' => 'img/img2.png'),
array('title' => 'title1', 'description' => 'description1', 'image' => 'img/img3.png'),
array('title' => 'title2', 'description' => 'description2', 'image' => 'img/img4.png'),
array('title' => 'title2', 'description' => 'description2', 'image' => 'img/img5.png'),
array('title' => 'title3', 'description' => 'description3', 'image' => 'img/img6.png')
);
?>
The problem with this kind of structure is duplicated title, description.
I'd like to get something like that:
<?php
array(
array('title' => 'title1', 'description' => 'description1', 'image' =>
array('img/img1.png', 'img/img2.png', 'img/img3.png')
),
array('title' => 'title2', 'description' => 'description2', 'image' =>
array('img/img1.png', 'img/img2.png')
),
array('title' => 'title3', 'description' => 'description3', 'image' =>
array('img/img6.png')
)
);
?>
My questions are:
Is it possible to get this kind of structure of data just with a SQL request (No PHP manipulation..)
If not, what kind of PHP manipulation I have to do to transform my first array to my second array?
Thanks!
Have a look at group clause and group_concat function. I'm not sure whether it creates an array in PHP, but it's almost what you want:
SELECT table1.title, table1.description, GROUP_CONCAT(table2.image) LEFT JOIN table2 ON table2.id = table1.id GROUP BY table1.id
You can use explode function in PHP to transform the result of GROUP_CONCAT(table2.image) to PHP array
See the documentation of MySQL's group_concat and PHP's explode functions.
You can do a select on all the distinct (Name, Description) tuples. Then you'll have an array of Name,Descriptions, and a null third element. Then loop through this array and get all the images for that distinct tuple. Then take that result and insert it into the third element.
Query get array of name/descriptions:
select distinct table1.title, table2.description left join table2 on table2.id = table1.id
Query to find all images of the distinct name/description tuples:
select table2.image inner join table1 on table1.id = table2.id where table1.name = arr[0] and table1.description = arr[1]
You can quite easily build the structure you're after when you iterate over the results, either was you're going to have to manipulate the result-set.
<?php
$items = array();
foreach ($rows as $row) {
if ( ! isset($items[ $row['title'] ])) {
$items[ $row['title'] ] = array(
'title' => $row['title'],
'description' => $row['description'],
'images' => array($row['image']),
);
continue;
}
$items[ $row['title'] ]['images'][] = $row['image'];
}
$items = array_values($items);
Anthony.
PHP code:
<?php
/*here is your result array*/
$result = array(
array('title' => 'tile1', 'description' => 'description1', 'image' => 'img/img1.png'),
array('title' => 'tile1', 'description' => 'description1', 'image' => 'img/img2.png'),
array('title' => 'tile1', 'description' => 'description1', 'image' => 'img/img3.png'),
array('title' => 'tile2', 'description' => 'description2', 'image' => 'img/img4.png'),
array('title' => 'tile2', 'description' => 'description2', 'image' => 'img/img5.png'),
array('title' => 'tile3', 'description' => 'description3', 'image' => 'img/img6.png')
);
/*creating a new formatted array*/
$newResult = array();
foreach($result as $value){
$newResult[$value['title']]['title'] = $value['title'];
$newResult[$value['title']]['description'] = $value['description'];
$newResult[$value['title']]['image'][] = $value['image'];
}
/*printing new final formatted array*/
print_r($newResult));
?>

Categories