We are using the Zend Framework in our company and thus we're using Zend_Db_Select.
Now we are building a query with it which is then (pre fetch) passed to a function.
The query is built as follows:
$select = $this->_selectAll()
->setIntegrityCheck(false)
->joinLeft('shop', $conShop, $colShop)
->joinLeft('ptool', $conPtool, $colPtool)
->where('ptool.product_id > 0')
->where('ptool.product_is_from_shop = 0')
;
Where $conShop and $colShop are something like:
$colShop = array('shop_id','shop_channel');
$conShop = "shop.shop_id = ptool.shop_id";
In a new method I want to get all joined tables and their columns that are going to be selected. So the $select gets passed to the method and now I would like to get something like this:
Array
(
['shop'] => Array
(
[0] => 'shop_id',
[1] => 'shop_channel',
...
),
['ptool'] => Array
(
[0] => 'shop_id',
[1] => 'ptool_id',
...
),
...
)
It would be nice if I can get this pre fetch.
The background is that I want to sort by shop_id for example and this table name is used in two joined tables. If I do something like "ORDER BY shop_id" I'd get the error that the column is ambiguous. That's why I need to know which columns belong to which table so that I can do something like "ORDER BY shop.shop_id"
Hope you can help me. Thanks! :)
Related
I have a database table with options that looks like this
I do a SELECT * FROM options and load all records into a recordset.
How do I then access just the optionValue of optionName = SMSactive
[EDIT]
Yes, I could do SELECT * FROM options WHERE optionName ='SMSactive' - I know that.
But as I said, since I have a recordset with a bunch of rows in it (from the SELECT), I want to pull a specific row where optionName = SMSactive
[EDIT]
If you are using PHP >= 5.5 you can use array_column() http://php.net/array_column
But if not, the question has already been asked and answered here PHP multidimensional array search by value
To access to all records with optionName = SMSactive the SQL should be:
SELECT * FROM `TableName` WHERE `optionName` = 'SMSactive'
if your array result from the query is something like this:
$array = array(
0 => array(
'optionName' => 'lala0',
'optionDescription' => 'lala01',
'optionValue' => 'lala03',
),
1 => array(
'optionName' => 'lala1',
'optionDescription' => 'ala2',
'optionValue' => 'SMSactive',
)
);
You can grab who has 'optionValue' => 'SMSactive', by this way
foreach ($array as $key) {
if ($key['optionValue'] == 'SMSactive') {
$filtered[]=$key;
}
}
echo '<pre>';
print_r($filtered);
echo '</pre>';
Side Note: If the array is very large you have to be careful with the memory...it's advisable just get from the db what you are using in the moment...IMO
Im trying to solve my issue with Yii Framework. I have a view that returns a $_POST :
Array ( [Questions] => Array ( [countries] => Array ( [0] => 1 ) [categories] => 1 ) [yt0] => Search )
Information like categories is single id, where countries is an array.
Now, my question is, how tu use properly the Yii model query builder so that I can include statement for many countries from an array.
Something
like:
"SELECT questions.name from questions WHERE countries.id == $_Post['Questions']['countries'][ 0 ] AND countries.id == $_Post['Questions']['countries'][ 1 ] AND .... + n times for countries"
When $_POST['Questions']['countries'] was returning only one id i used the following :
$model = Questions::model()->with(
array( 'countries' => array (
'select' => 'name',
'condition' => 'countries.id=:cou_id', // How to do for array?
'params' => array (':cou_id' => $_POST["Questions"]["countries"]) // How to do for array ?
)
)
)->findAll(array ('select' => 'question'));
How to do for multiple countries ? How to include foreach loop with the Yii:model query builder ?! Pls help.
Ultimately the condition property of the criteria needs to include a fragment that uses the MySql IN function, e.g. countries.id IN (x, y, z, ...). You can do that manually, but Yii provides the convenience method CDbCriteria::addInCondition to help:
$countryCriteria = new CDbCriteria();
$countryCriteria->select = 'name';
$countryCriteria->addInCondition('id', $_POST["Questions"]["countries"]);
$model = Questions::model()->with(array('countries' => $countryCriteria))
->findAll(array('select' => 'question'));
The following code works :
$criteria = new CDbCriteria();
$criteria->with = array('countries');
$criteria->addInCondition('countries.id' , $_POST['Questions']['countries']);
$model = Questions::model()->findAll($criteria);
I like how CakePHP automatically loops through the results of MySQL queries and formats them in a nice map for you.
Here's a sample query that I'm using:
# Inside some model
return $this->query("
SELECT
Profile.id,
SUM( IF( HOUR(Log.event_one) > 3, 1, 0 ) ) as EventOne
FROM profiles Profile
JOIN logs Log ON Log.id = Profile.log_id
WHERE Profile.id = {$pUserId}
");
CakePHP would return a map like the following as the result:
array
0
array
'Profile'
array
'id' => 23
'0'
array
'EventOne' => 108
1
array
'Profile'
array
'id' => 23
'0'
array
'EventOne' => 42
2
...
What I'm trying to do is have the result be something like this:
array
'Profile'
array
'id' => 23
'Events'
# ^ I want to be able to specify this key
array
'EventOne' => 108
Any ideas?
You can't do that directly
The top level array keys are derived from the table name which mysql says the field relates to - in your case it's a calculated field and therefore (according to mysql) belongs to no table - hence the 0 array key.
Post processing
What you can do however, is post process the result so that it is the format you want:
public function getStuff() {
// The query call in the question can very easily be a normal find call
$return = $this->query("don't use query unless you have no choice");
foreach($return as &$row) {
$row['Events'] = $row[0];
unset($row[0]);
}
return $return;
}
I have a simple query like this
SELECT hometeam.name AS hometeamName, hometeam.shortname AS hometeamShortName,
roadteam.name AS roadteamName, roadteam.shortname AS roadteamShortName,
smatch.startdate
FROM smatch
JOIN team hometeam
ON smatch.hometeamid = hometeam.uid
JOIN team roadteam
ON smatch.roadteamid = roadteam.uid
which be default returns a one dimensional array, like this:
array(5) {
["homeTeamName"] => "Brasil"
["homeTeamShortName"] => "BRA"
["roadTeamName"] => "Norway"
["roadTeamShortName"]=> "NOR"
["startdate"]=> "1309709700"
}
Question is, is there a mysql-way to let the result be a nested array, with a structure like the following?
result =>
hometeam =>
name
shortname
roadteam =>
name
shortname
startdate
And if not, is there a (php) post processing best practice to do this conversion?
Many thanks,
Robson
I don't think there's a way to directly get the result you want, but to generate that array after the query shouldn't be hard.
Something like this?
foreach($rows as $row) {
$resultArray[] = array(
'hometeam' => array(
'name' => $row['homeTeamName'],
'shortname' => $row['homeTeamShortName']
),
'roadteam' => array(
'name' => $row['roadTeamName'],
'shortname' => $row['roadTeamShortName']
),
'startdate' => $row['startdate']
);
}
MySQL (or any database) has no concept of arrays.
The only way I can think of is that you'd need to do it in a Stored Procedure and serialise the result in some way - essentially creating a serialised string... wich you'd then need to re-construct the array from.
However, would be better doing this in PHP to be honest, the gain from doing it in an SP will be minimal. Will be more efficient to query the main and then query within using loops PHP-side.
You have to fetch the result in PDO::FETCH_CLASS mode.
by specifying the __set()-method respectively you can store the result-field-data how ever you like.
This class should also extend ArrayAccess so you can access it like an array or have it return one.
I am having a play around with codeigniter and trying to get my head around the active record system and such like.
I have set up a couple of tables and am attempting to run a join on them, as such:
function GetOrganisationsAndBuildingDetails()
{
$this->db->select('organisations.organisation_name,
organisations.organisation_id,
buildings.building_name,
buildings.address1');
$this->db->from('organisations')->join('buildings', 'buildings.organisation_id = organisations.organisation_id');
$query = $this->db->get();
return $query->result();
}
In my database i have one organisation with two related buildings. The above query returns two objects (one for each building) - however, the organisation is duplicated.
stdClass Object (
[organisation_name] => This is an example org
[organisation_id] => 1
[building_name] => test building
[address1] => 123456 )
stdClass Object (
[organisation_name] => This is an example org
[organisation_id] => 1
[building_name] => teeeest building
[address1] => 123456 )
I suppose I was expecting something along the lines of one return object with a series of nested objects for related buildings. Is this possible?
If not, is their a recommend way of arranging the return data so I can easily loop through it in the view? (foreach org, foreach building etc etc).
Apologies if I'm being a little dense here. Im coming from .net and (linq to SQL in particular) where this stuff is a little different)
The query will inevitably return duplicate data as you say, you have to organize them after you get the result like this
$buildings = array();
foreach ( $result_object as $organization ) {
$building_data = array(
'building_name' => $organization->building_name,
'address' => $organization->address,
);
$buildings[$organization->organization_name][] = $building_data;
}
this way organizations will be "compacted" in the first key of the multidimensional array, and one level deeper you will have info about the buildings. Hope this helps.