Codeigniter not showing proper results for array fetched by MySQL query. - php

I am working with Codeigniter with mysql databases,
I have a model function
public function get_all_data(){
$this->output->enable_profiler(TRUE);
$years = $this->input->post('year');
$months = $this->input->post('month');
$exec_ids = $this->input->post('exec_id');
$query = $this->db->query("SELECT * FROM client_booking AS cb
RIGHT OUTER JOIN executive_client_unit_relation AS ecur ON cb.id = ecur.booking_id
LEFT OUTER JOIN new_invoice ON cb.id = new_invoice.booking_id
WHERE ecur.executive_id IN (" . implode(',', $exec_ids) . ") AND MONTH(cb.booking_date) IN (" . implode(',', $months) . ") AND YEAR(cb.booking_date) IN (" . implode(',', $years) . ")");
return $query->result();
}
The sql generated by this is (as seen in the profiler) :
SELECT * FROM client_booking AS cb
RIGHT OUTER JOIN executive_client_unit_relation AS ecur ON cb.id = ecur.booking_id
LEFT OUTER JOIN new_invoice ON cb.id = new_invoice.booking_id
WHERE ecur.executive_id IN (4,5,6) AND MONTH(cb.booking_date) IN (1,2,3,4,5) AND YEAR(cb.booking_date) IN (2013,2014)
My problem is that the booking_id value is set to NULL when I var_dump() the result of this query.
On the other hand, when I run the SQL in my phpmyadmin, everything goes well and I can see the booking_id
PS: client_booking table's primary key is id which is the booking_id for all the other tables.
Can anyone help me to resolve this?

You are using LEFT/RIGHT joins so when there is no association found between your tables a null row will be returned ,second thing is your tables new_invoice and executive_client_unit_relation both have common names for the column name booking_id and in your select statement you are doing select * so for the columns with same name i guess the last one is picked which is null,for the solution you either you select only needed columns not all like SELECT cb.* or either the columns have same name with your query table then specify them individually with the alias you wish to provide but in the end of select statement in query like SELECT *,cb.id AS booking_id,....

Related

Select from Multiple table, but ignore if not found

Using this query I'm selecting rows from multiple tables. Unfortunately, if a row does not exist in one table, then rows in all tables won't return. It's because I'm using AND operator.
So, I want this query to be modified, where will ignore a table if value is not found, but return rest of the tables where the value is found.
Here's the MySQL query:
foreach ($courseArr as $term) {
$term = trim($term);
if (!empty($term)) {
$courseSectionSql[] = "courseDataApp.course = '$term' AND courseDataApp.section = '$sectionArr[$i]'";
$i++;
}
}
$data = $db->rawQuery("SELECT courseDataApp.*, facultyDatabase.*, books.*
FROM courseDataApp
INNER JOIN facultyDatabase ON facultyDatabase.initial = courseDataApp.faculty
INNER JOIN books ON books.course = courseDataApp.course WHERE ".implode(' OR ', $courseSectionSql));
Here's what is returns:
{
"id":11,
// courseDataApp values
"faculty":"AKH1",
"course":"CSE241",
"section":"7",
.
.
.
.
.
.
.
// facultyDatabasevalues
"initial":"AKH1",
"name":"Ms. Kamal Habi",
"dept":"ECE",
.
.
.
.
.
.
// books values
"books": "Digital Logic Design"
},
So the problem is, when a value from facultyDatabase or books tables not found, rest of the data won't return. I just want it to ignore that, show what's found. Like Union.
As some of the comments point out you are using outdated syntax that INNER JOINs the tables which leads to the result you get. You need to LEFT JOIN the tables. Hence you will have a result even though there are no entries in the LEFT JOINed tables. Something like this should work
SELECT courseDataApp.*, facultyDatabase.*, books.*
FROM courseDataApp
LEFT JOIN facultyDatabase ON facultyDatabase.initial = courseDataApp.faculty
LEFT JOIN books ON books.course = courseDataApp.course
WHERE courseDataApp.course = '$term'
AND courseDataApp.section = '$sectionArr[$i]'
Written like this you would have an equivalent to your query in current syntax that will not return anything if there are no entries in the INNER JOINed tables.
SELECT courseDataApp.*, facultyDatabase.*, books.*
FROM courseDataApp
INNER JOIN facultyDatabase ON facultyDatabase.initial = courseDataApp.faculty
INNER JOIN books ON books.course = courseDataApp.course
WHERE courseDataApp.course = '$term'
AND courseDataApp.section = '$sectionArr[$i]'

select from two mysql tables where column value is similar and id is retrieved from previous page

i have a question. my english isn't well. so i hope i explain well...
i have two tables, tbl_home and tbl_office, the question is
how do i make a select statement from 2 tables which have identical value from column 'case_no' where it is referenced in both table..
$a=$_POST['home_id']
the code above is where i get the home_id from,
while the statement below is how i try to select both tables based on value in column 'case_no' of both table. but it is based on variable $a which i retrieved from form
<?php
$sql2 = "SELECT * FROM tbl_office WHERE case_no IN (SELECT * FROM tbl_home WHERE home_id = '$
$result2=$conn->query($sql2);
while($row = $result2->fetch_assoc()){
$a=$row['case_no'];
$bc=$row['colour'];
echo " $a <br/> ";
echo " $bc2 <br/>";
?>
is the select statement above correct??
soo, i just want anybody to take a look a this specific statement and how to make it right
$sql2 = "SELECT * FROM tbl_office WHERE case_no IN (SELECT * FROM tbl_home WHERE home_id = '$a'";
You need inner join to use:
" SELECT t_office.home_id,t_office.case_no,t_office.name FROM tbl_office
t_office INNER JOIN tbl_home t_home ON t_office.case_no = t_home.case_no;
where t_office.case_no ='$a'";
u can use "inner join" for example:
"SELECT t.home_id,t.case_no,t.name FROM tbl_office
t INNER JOIN tbl_home h ON h.case_no = h.case_no"
**select tbl_home.name,tbl_office.case_no,tbl_office.color from tbl_office
INNER JOIN tbl_home on tbl_office.case_no = tbl_home.case_no
where tbl_office.case_no ='$a';**
I hope this will be working fine until $a(case_no) value is existed in tbl_home or else it doesn't give any rows

SQL - join 2 tables but return all if 1 table empty

Using CodeIgniter Active Records:
$country = $_SESSION['search'];
$min_price = $_SESSION['min_price'];
$max_price = $_SESSION['max_price'];
$condition = "";
$this->db->select('*,attachments.title as image');
$this->db->from('details');
$this->db->join('attachments', 'attachments.parent = details.id');
$this->db->where('attachments.type', 'quotes');
if ($country != '')
{
$condition .= "(details.service_location IN ('" . $country . "') OR details.country in ('" . $country . "'))";
$this->db->where($condition);
}
$this->db->where('details.price_range_from >=', $min_price);
$this->db->where('details.price_range_to <=', $max_price);
$this->db->group_by("attachments.parent");
$this->db->order_by("details.created_on", "asc");
$query = $this->db->get();
$result = $query->result();
return $result;
}
I have 2 tables say details and attachments, and I want to do a join on them.
Table details will always have records in it.
When table attachments has rows in it, I want the query to turn all the rows in which table details and table attachments matches. (i.e. behave like inner join)
However, if table attachments is empty, I'd like to return everything from table details.
and also checking table attachments in where condition.
Is this possible to do in 1 query?
Thanks.
Use LEFT OUTER JOIN rather than JOIN
FROM (details)
LEFT OUTER JOIN attachments ON attachments.parent = details.restaurant_id
UPDATE
and of course
GROUP BY details.restaurant_id
rather than attachments.parent
Although I think it's a bit weird requirement, the principal structure you can use is:
inner join
union
select *, ... from details where 0 = (select count(*) from attachments where ...)
If the inner join doesn't return rows, the second query will return all details.
If the inner join returns rows, the second query won't return anything because attachments are found (count(*) returns some positive value).
I think you can fill in the details yourself.
I don't guarantee for brilliant performance.
Use two different queries, check if attachments has rows and run query with inner join details else return rows from details table
IF EXISTS (SELECT * FROM #attachments where column1='')
BEGIN
SELECT * FROM attachments as atc
INNER JOIN details AS det ON atc.parent = det.restaurant_id where column2=''
END
ELSE
SELECT * FROM details where column2=''

Join drops variable if it is not common to both tables

I have two tables and the commonality is the tid. the $tid is the primary key for tourneys and if it is in team_tourney then the team selected it. The code below echos everything if a team selected it but drops only the variable $tid for every non selected item. How would you suggest I work around my delema.
tables
team_tourneys
tourneys
my sql is
$myChoice=#mysql_query("SELECT *
FROM tourneys
LEFT JOIN team_tourneys
ON tourneys.tid = team_tourneys.tid
WHERE tourney_state = '$region' AND tourney_start_date >= now()
GROUP BY tourneys.tid ORDER BY tourney_start_date ASC
");
if (!$myChoice)
{
die('<p>Error fetching Tourney details: ' .
mysql_error() . '</p>');
}
while ($choice = mysql_fetch_array($myChoice))
{
$tid = $choice['tid'];
$tourney_name = $choice['tourney_name'];
echo ''.$tourney_name.'</div>'
}
Since you are fetching into an associative array you only have one slot for any selected column name (or alias). In other words, you can not have:
array(
"tid" => 1,
"tid" => 2,
);
Your query is going to return all columns of all referenced tables in the order the tables are listed. Since the both tables contain tid and team_tourneys is the last table referenced, $choice["tid"] will contain team_tourneys.tid which of course can be NULL due to the LEFT JOIN.
Probably the easiest way to resolve this is to read the tourneys table last:
SELECT team_tourneys.*, tourneys.*
FROM tourneys
LEFT JOIN team_tourneys
ON tourneys.tid = team_tourneys.tid
WHERE tourney_state = '$region' AND tourney_start_date >= now()
GROUP BY tourneys.tid ORDER BY tourney_start_date ASC;
You should really enter each column name individually, however. It's bad practice to use *.

Not a unique table/alias stock:

Ive got the query below :
$sql = "SELECT `scanners`.`KordNo`, `scanners`.`BundleNumber`
FROM `scanners`, `TWOrder`, `Stock`
INNER JOIN `TWORDER` ON `scanners`.`KordNo` = `TWOrder`.`KOrdNo`
AND `scanners`.`Date` = '" . $date . "'
INNER JOIN `Stock` ON `TWOrder`.`Product` =`Stock`.`ProductCode`
AND `Stock`.`ProductGroup` NOT BETWEEN 400 AND 650
AND `scanners`.`Scanner` IN (
ORDER BY `scanners`.`KordNo` ASC";
foreach($scanner as $x)
{$sql .= $x . ",";}
$sql .= "0);";
// And query the database
$result = mysql_query($sql);
while($row = mysql_fetch_array($result))
$return[] = $row;
}
When i echo the sql on php my admin i get the error not a unique table/alias stock;
can someone advise?
Since you're using explicit JOINs, drop the other two tables off of the FROM clause.
...
FROM `scanners`
INNER JOIN `TWORDER` ON `scanners`.`KordNo` = `TWOrder`.`KOrdNo`
...
On line 2 you have...
FROM `scanners`, `TWOrder`, `Stock`
Then you have some INNER JOINs on to TWOrder and Stock.
That's mixing syntax (, and JOIN) which is messy. Stick to JOIN
It means that TWOrder and Stock are mentioned Twice in the query
If you REALLY need to include those table multiple times in one query, you need to give them alias names, so they can be distiguished from each other.
But I think it's probably a mistake and that Line 2 should just be
FROM `scanners`
Then, also, I'm not sure how you got that to compile. You have IN ( and then an ORDER BY clause, to which you append a list of values. You should append the list before the ORDER BY and then append the ORDER BY after you've finished the loop.

Categories