Queries with conditional queries - php

Let's say i have a query with quite a number of joins and subqueries in one php file that handles queries.
Nb: i put an example of what $query looks like at the bottom
$query = query here;
if ($query) {
return $query->result();
} else {
return false;
}
}
Then in my php file that handles the html, i have the usual foreach loop with some conditions that require making other queries e.g;
Note: result houses object $query->result().
foreach ($results as $item) {
$some_array = array();
$some_id = $item->id;
if ($some_id != 0) {
//id_return_other_id is a function that querys a db table and returns the specified column in the same table, it returns just one field
$other_id = id_return_other_id($some_id);
$some_query = another query that requires some joins and a subquery;
$some_array = the values that are returned from some_query in an array
//here i'm converting obj post into an array so i can merge the data in $some_array to item(Which was converted into an array) then convert all of it back into an object
$item = (object)array_merge($some_array, (array)$item);
}
//do the usual dynamic html stuff here.
}
This works perfectly but as i don't like the way i'm doing lot's of queries in a loop, is there a way to add the if $some_id != 0 in the file that handles queries?
I've tried
$query = query here;
//declaring some array as empty when some_id is 0
$some_array = array();
if ($query) {
if ($some_id != 0) {
//same as i said before
$other_id = $this->id_return_other_id($some_id);
$some_query = some query;
$some_array = array values gotten from some query;
}
$qresult = (object)array_merge($some_array, (array)$query->result);
return $qresult;
} else {
return false;
}
}
This doesn't work for obvious reasons, does any one have any ideas?
Also if there's a way to make these conditions and queries in the $query itself i'd love you forever.
Ps: A demo query would be something like
$sql = "SELECT p.*,up.*,upi.someField,etc..
FROM (
SELECT (another subquery)
FROM table1
WHERE table1_id = 3
UNION ALL
SELECT $user_id
) uf
JOIN table2 p
ON p.id = uf.user_id
LEFT JOIN table3 up
ON .....
LEFT JOIN table4
ON ....
LEFT JOIN table5
ON ....
And so on..etc..
ORDER BY p.date DESC";
$query = mysql_query..

It seems like you just need to run two queries in your query file. The first query would get a broad set of what you’re looking for. The second query would query an id that’s in the result and perform a new query to get any details about that particular id. I use something similar to this in the customer search page for my application.
$output = array();
$query1 = $this->db->query("SELECT * FROM...WHERE id = ...");
foreach ($query->result_array() as $row1)
{
$output[$row1['some_id']] = $row1;
$query2 = $this->db->query("SELECT * FROM table WHERE id = {$row1['some_id']}");
foreach ($query2->result_array() as $row2)
{
$output[$row1['some_id']]['data_details'][$row2['id']] = $row2;
}
}
Then in your page that displays html, you’ll just need two foreaches:
foreach($queryresult as $key=> $field)
{
echo $field['some_field'];
foreach($child['data_details'] as $subkey => $subfield)
{
echo $subfield['some_subfield'];
}
}
I know you’re using objects, but you could probably convert this to use that format. I hope this makes sense/helps.

use this
if ($some_id !== 0) {
instead of
if ($some_id != 0) {

Related

Select value from foreach result

Hi is there a way to get the value from each foreach result.
For Example I have a table named tblsamp.
id | data |
1 | d1 |
2 | d2 |
3 | d3 |
then put some query:
$query = $this->db->query("SELECT * FROM tblsamp");
foreach ($query->result() as $row){
echo $row->data .'<br>';
}
Result is:
d1
d2
d3
Now what I want is I want to get the value of the first result and compare the value from another table, and so on...
For Example:
if('d1' == '(value from another table)'{
\\do something here
} else if ('d2' == '(value from another table)'{
\\and so on.....
}
how can I do this guys? TIA!.
It looks like you are using codeigniter based off the $this->db->query syntax. With codeigniter you can change a table into an array using $query->result_array().
If you are sure both tables have the same amount of rows, you can use something like the following.
$query = $this->db->query("SELECT * FROM tbl1");
$table1 = $query->result_array();
$query = $this->db->query("SELECT * FROM tbl2");
$table2 = $query->result_array();
for ($x = 0; $x <= count($table1); $x++) {
if ($table1[$x] === $table2[$x]) {
//DO SOMETHING HERE
}
}
If $table1 might have more rows than table2, I would change it to
$query = $this->db->query("SELECT * FROM tbl1");
$table1 = $query->result_array();
$query = $this->db->query("SELECT * FROM tbl2");
$table2 = $query->result_array();
for ($x = 0; $x <= count($table1); $x++) {
if (isset($table1[$x]) && isset($table2[$x])) {
if ($table1[$x] === $table2[$x]) {
//DO SOMETHING HERE
}
} else {
break;
}
}
You can find you have matches in 2 tables however you may want to do more research about How SQL query can return data from multiple tables
How can an SQL query return data from multiple tables
This may work for your basic example
$query = $this->db->query("SELECT * FROM tblsamp,tblother");
$rst = mysql_query($query);
if(mysql_affected_rows() > 0) {
while($row = mysql_fetch_array($rst)) :
if($row['data'] == '$row['otherdata']') {
echo 'you got a match' . $row['data'] . ' In table sample to ' . $row['otherdata'] . ' In other table<br>';
}
else {
echo ' no match found in results;
}
}
endwhile;
You could add a query within your query, but this is not recommended -- things can get REALLY slow. It might be something like this:
// your original query
$query = $this->db->query("SELECT * FROM tblsamp");
foreach ($query->result() as $row){
// for each record in your original query, we run a new query derived from the result
// OBVIOUSLY you need to change this line of code to be specific to
// your database table's structure because some_col is probably not
// the name of a column in your database
$subquery = $this->db->query("SELECT * FROM other_table WHERE foo=" . $row->some_col);
$subrows = $subquery->result();
// output $subrows here?
// note that $subrows might be an array with any number any number of records
}
the exact code will depend on the db classes you are using. It's codeigniter, if I'm not mistaken? EDIT: it is codeigniter.
The correct solution here is going to depend on your database table definitions. I would strongly suggest creating a JOIN using CodeIgniter, but can't offer much more advice without some idea of what your db structures are going to look like and how many records in the second table exist for each record in the first table.

MySQL select many tables, each table's results being it's own key/val pair

Hopefully this isn't a stupid question, was hard to explain in the title but...I have a certain amount of tables and most of them don't have the same structure...except startDate. For example, say there's three tables with column structures like this:
t1:
id a b c startDate
t2:
id e f g h i startDate
t3:
id j k startDate
I want to get them all into a result which will look something like this json type format:
[{"t1":array({
//all rows for t1
})
},{"t2":array({
//all rows for t2
})
},{"t3":array({
//all rows for t3
})
}]
I want to be able to do something like this in PHP:
foreach ($results as $key => $val) {
if ($key == "t1") {
//parse t1 $val array
}elseif ($key == "t2") {
//parse t2 $val array
}elseif ($key == "t3") {
//parse t3 $val array
}
}
I know it's possible with UNION ALL but I would have to do NULL values for columns so if I had 6 or 7 tables, the query would be really messy. Is there a way to use GROUP_CONCAT to get the desired result, also with a startDate BETWEEN arg1 AND arg2?
Or...would it be best to do a for loop and query each table, then put it all together in PHP?
Please try this
//db connection
$json = array();
$tables = array("t1","t2","t3");
for($i=0;$i<count($tables);$i++){
$rows = array();$row = array();
$sql = "SELECT * FROM $tables[$i]";
$result = mysql_query($sql);
while($row = mysql_fetch_assoc($result)){
$rows[] = $row;
}
$json[$tables[$i]] = $rows;
}
//you can use print_r($json) to display the array or json like
echo json_encode($json)

PHP inserting array into an object

I am trying to inject an array into an object but it's just not working. This is what I am doing:
1) Get a specific Match record from the database
2) Get all the Player records from the database that are associated with that match
3) Add them players to the Match object
Code:
$matchQuery = "SELECT * FROM matches where new = 1 order by date asc limit 1";
$matchResult = mysql_query($matchQuery,$link) or die('Errant query: '.$matchQuery);
/* create one master array of the records */
$matches = array();
if(mysql_num_rows($matchResult)) {
while($match = mysql_fetch_assoc($matchResult)) {
$playersQuery = "SELECT p.* FROM match_players mp
LEFT JOIN players p on p.id = mp.player_id
WHERE mp.match_id = '$match->id'";
$playerResult = mysql_query($playersQuery,$link) or die('Errant query: '.$playersQuery);
$players = array();
if(mysql_num_rows($playerResult)) {
while($player = mysql_fetch_assoc($playerResult)) {
$match->players[] = $player; //<-- This doesn't seem to work
}
}
$matches[] = $match;
}
}
The objects within Match are being spat out, BUT, the Players are not.
$match is an array, the result of the deprecated mysql_fetch_assoc(). So $match->players[] = $player; is not going to work.
If there is no players key in the sql result, you can add it to the array:
$match['players'][] = $player;
Otherwise you would have to use a different key.
Another problem is your query in the loop: You use $match->id and that should be $match['id'] as $match is an array.
By the way, doing sql queries in a loop is never a good idea, you should try to get your results in one query joining the different tables.
$match["players"] = array();
while($player = mysql_fetch_assoc($playerResult)) {
$match["players"][] = $player;
}

Display grouped sql results

I have a sql query that groups results. The print_r shows the results I would like are there. Now I would like to display these results in table groups i.e. Table One with a list of all the seats with that table, Table Two etc.
I have tried all kinds of things to get this done to no avail... here is the code. I can easily display the records - but would like to display them by groups arghhh
$seatings = $wpdb->get_results("SELECT
bb_cl_seating.table,
bb_cl_seating.seat,
bb_cl_seating.seat_id,
bb_events_attendee.fname,
bb_events_attendee.lname,
bb_events_attendee.email
FROM bb_cl_seating
LEFT JOIN bb_events_attendee
ON bb_cl_seating.id = bb_events_attendee.id
WHERE bb_cl_seating.event_id = '1' ");
foreach ($seatings as $seating) {
} // Ends foreach
$seatings = $wpdb->get_results("SELECT
bb_cl_seating.table,
bb_cl_seating.seat,
bb_cl_seating.seat_id,
bb_events_attendee.fname,
bb_events_attendee.lname,
bb_events_attendee.email
FROM bb_cl_seating
LEFT JOIN bb_events_attendee
ON bb_cl_seating.id = bb_events_attendee.id
WHERE bb_cl_seating.event_id = '1' ");
foreach ($seatings as $seating => $group) {
//$data[table] = seat,seat2,seat3...
$data[$group[1]] = $data[$group[1]].','.$group[2];
} // Ends foreach
In this example create one array $data of tables with yours seats sort by ','.
Its help?
This did the trick - hope it helps someone else:-)
$seatings = $wpdb->get_results("SELECT bb_cl_seating.table, bb_cl_seating.seat, bb_cl_seating.seat_id, bb_events_attendee.fname, bb_events_attendee.lname, bb_events_attendee.email
FROM bb_cl_seating
LEFT JOIN bb_events_attendee ON bb_cl_seating.id = bb_events_attendee.id
WHERE bb_cl_seating.event_id = '1'
ORDER BY bb_cl_seating.table, bb_cl_seating.seat
");
$table_title = '';
foreach($seatings as $result => $col) {
if($table_title !== $col->table) {
$table_title = $col->table;
echo "<strong>$table_title</strong>";
echo "<br />";
}

Loop returning unexpected results

Am try to looping through a database result set, the problem is that i know i have only one row of data, yet the loop returns 5 rows
This is my method from my model
function get_latest_pheeds() {
$data = $this->user_keywords($this->ion_auth->user_id);
$keyword = $data;
$user_id = $this->ion_auth->user_id;
foreach($keyword as $key => $word) {
$q = "SELECT *,COUNT(pheed_comments.comment_id) as comments
FROM pheeds
LEFT JOIN pheed_comments ON pheed_comments.P_id=pheeds.pheed_id
WHERE pheed LIKE '%$word%' OR user_id='$user_id'
GROUP BY pheeds.pheed_id
ORDER BY datetime DESC";
$result = $this->db->query($q);
$rows[] = $result->result();
}
return $rows;
}
What am i doing wroing
This is because your query has an OR where it should probably have an AND - each query always matches the user_id='$user_id'.
This loop is quite inefficient anyway, I think you want to do something more like this:
function get_latest_pheeds() {
$keywords = $this->user_keywords($this->ion_auth->user_id);
$q = "SELECT *,COUNT(pheed_comments.comment_id) as comments
FROM pheeds
LEFT JOIN pheed_comments ON pheed_comments.P_id=pheeds.pheed_id
WHERE (pheed LIKE '%".implode("%' OR pheed LIKE '%",$keywords)."%') AND user_id='".$this->ion_auth->user_id."'
GROUP BY pheeds.pheed_id
ORDER BY datetime DESC";
return $this->db->query($q);
}
If you want your results returned as an array like they were previously, you'll need to loop over results and fetch each of them into an array key of another array. I can't do it here because I can't see your db class...
EDIT: Slight fix in the above code...
ANOTHER EDIT: another fix...

Categories