I have this SQL query which is something like this in normal sql syntax
SELECT *
FROM question
LEFT JOIN abcd_selection ON question.questionID = abcd_selection.questionID
WHERE question.SurveyID =21
This works perfectly fine I get what i wanted. However when I switch this over to CI, it does not work strangely. The questionID column disappears for rows that do not have a match with abcd_selection.
$this->db->select('*');
$this->db->from('question');
$this->db->join('abcd_selection','question.QuestionID = abcd_selection.QuestionID', 'left');
$this->db->where('question.SurveyID', $input_qid);
$query = $this->db->get();
Can anyone solve this??
When joining 2 tables, which have the same column name, you will get a NULL value when there is not a row that matches in the second table.
question.SurveyID question.QuestionID abcd_selection.QuestionID
1 2 2 //matching row in abcd_selection
2 3 NULL //no matching row in abcd_selection
Since the column names are the same, php will select the last instance of QuestionID, which will be NULL when a matching row does not exist.
One way to work around this is to select the column as an alias
$this->db->select('*,question.QuestionID as QID');
Now you can select $query['QID'] even when a abcd_selection.QuestionID does not exist.
Related
I have a problem and don't know why my mysqli query does not work correctly in PHP.
I have two tables:
table 1 "reviews"
id | dateCreated | reviewText | ...
table 2 "issues"
id | reviews_id | issueText | ...
Table 1 contains reviews from users. Table 2 contains issues (complaints) for certain reviews. However one review does not necesarrily need to have a issue (if nobody reported it). The query is:
SELECT reviews.*, issues.*
FROM reviews
LEFT JOIN issues
ON reviews.id=issues.reviews_id
WHERE (reviews.idVenue='6438' OR reviews.idVenue='6444' OR reviews.idVenue='7590' )
ORDER BY 'reviews.updated' DESC
This works perfectly if one issue exists for a review (ON clause is true).
However if there is no issue existing for the review (the ON clause is not true), then reviews.id and issues.reviews_id are missing in the $row that was fetched with
if($result = $this -> mysqli -> query($qstr)){
while($row = $result->fetch_assoc()){
$temp[] = $row;
}
}
Also all the other colums from issues are missing in $row because they are NULL. With missing I mean, that they are not there if I print $row or check $row as a watch variable in the netbeans debugger. It just doesn't show reviews.id and issues.reviews_id.
If I run the query above directly in phpmyadmin, then it returns all columns correctly with the value NULL for the cases where no related issue was found for a review.
So my question is, why does PHP ignore the NULL values and does not return them in $row but phpmyadmin does?
Thanks!
Here's my comment in more descriptive information in case someone runs into this in the future.
When you call fetch_assoc php assign columns names as keys & their values as the values of the array, As the keys of an array are unique any entry that holds the same id will be overwritten.
In your example both reviews & issues have a column named 'id' therefore you'll always get the value from the last 'id' column you used in your select statement.
An easy fix for this (without having to permanently change your columns names) is to use aliases in your query.
e.g: SELECT reviews.*, issues.id as `issue_id`, issues.issueText
I have 2 Table from where I want customerid, customername, comment and customercontactno.
I use Following query For Join 2 Table.
SELECT comment.id, comment.Kommentar, comment.Kunde,
CONCAT_WS('', customer.telefonPrivat, customer.TelefonMobil) AS Contact_Phone
FROM tbl_test_comment comment
LEFT JOIN tbl_test_customer customer
ON customer.id = comment.Kunde;
My First table is tbl_test_comment With following data
And tbl_test_customer
Result Of Above Query
ISSUE
When I run above query, Its working fine if one of two merged column is empty. But it merge data if data are in both row. I want to avoid one if both row have value.
Expected Output
concat_ws stands for "concatenate with separator", that is, add the strings together with the separator in between.
Instead, use the coalesce function, which returns the first non-null argument:
coalesce(customer.telefonPrivat, customer.TelefonMobil)
If an empty telephone number can be an empty string '' as well as null, you can use the more powerful case statement:
case
when length(customer.telefonPrivat) > 0 then customer.telefonPrivat
else customer.TelefonMobil
end
I have 2 tables in my database which I need to join.
1 table is the artikelen table and the other one is the collecties table. I currently have.
$this->db->select('*');
$this->db->from('collecties');
$this->db->join('artikelen', 'artikelen.collecties_id = collecties.id');
It gives the right result but all the double fields (collecties has a title field and artikelen has a title field) will become one (it returns the artikelen.title field), and I can't access the row of the other table (the collecties.title field).
I select 10 fields from artikelen and only collecties.title from collecties.
What is the simples way to do this without having to replace
$this->db->select('*');
with all the 10 fields with an as statement.
Make sure your both table got rows on your joining condition , otherwise it will return null. and modify the select as follows
$this->db->select('artikelen.*,collecties.title as ctitle');
I'm using codeigniter.
We have two mysql tables.
What I'm doing is taking all the details in the first table and feeding it to an html page to let all users to view it. But now I want to add some details from a second table related to a column in first table.
I mean, I have a column in first table call "Pending_on" in that column I have inserted some branch names
and in the second table I have inserted the contact details of those departments.
So, if we think in the first table fifth row pending_on column has the value "HR" then I want to display the telephone number of the HR department.
So, how can I write a query for this?
For your case, here is an example:
There are 2 tables named entry and subscription.
entry
field1 publisherId
field2 entry
subscription
field1 myId
field2 friendId
You can use a JOIN. In plain SQL:
SELECT e.publisherId, e.entry
FROM entry e
JOIN subscription s
ON s.friendId = e.publisherId
WHERE s.myId = 1234
this is the query i used to do my work
and thanks goes to MR. Yuvvaraj Bathrabagu
$this->db->select('*');
$this->db->from('new_users');
$this->db->join('contact', 'new_users.pending_on = contact.dep','left');
$query = $this->db->get();
$data = $query->result_array();
Let's take your example. You have a column name pending_on in your first table, and in your second table you have your department_name column. Find the below code for joining those two tables,
$this->db->select('firsttable.*,secondtable.contact_details');
$this->db->from('firsttable');
$this->db->join('secondtable', 'firsttable.pending_on = secondtable.department_name','left');
$query = $this->db->get();
So, The department_name in second table and pending_on in first table should have the same value as you mentioned "HR". And my suggestion is to have the id's of the table as reference instead of department names. Hope This helps.
I want to do a SELECT on an empty table, but i still want to get a single record back with all the column names. I know there are other ways to get the column names from a table, but i want to know if it's possible with some sort of SELECT query.
I know this one works when i run it directly in MySQL:
SELECT * FROM cf_pagetree_elements WHERE 1=0;
But i'm using PHP + PDO (FETCH_CLASS). This just gives me an empty object back instead of an row with all the column names (with empty values). So for some reason that query doesn't work with PDO FETCH_CLASS.
$stmt = $this->db->prepare ( $sql );
$stmt->execute ( $bindings );
$result = $stmt->fetchAll ( \PDO::FETCH_CLASS, $class );
print_r($result); // Empty object... I need an object with column names
Anyone any idea if there's another method that i can try?
Adding on to what w00 answered, there's a solution that doesn't even need a dummy table
SELECT tbl.*
FROM (SELECT 1) AS ignore_me
LEFT JOIN your_table AS tbl
ON 1 = 1
LIMIT 1
In MySQL you can change WHERE 1 = 1 to just WHERE 1
To the other answers who posted about SHOW COLUMNS and the information scheme.
The OP clearly said: "I know there are other ways to get the column names from a table, but i want to know if it's possible with some sort of SELECT query."
Learn to read.
Anyway, to answer your question; No you can't. You cannot select a row from an empty table. Not even a row with empty values, from an empty table.
There is however a trick you can apply to do this.
Create an additional table called 'dummy' with just one column and one row in it:
Table: dummy
dummy_id: 1
That's all. Now you can do a select statement like this:
SELECT * FROM dummy LEFT OUTER JOIN your_table ON 1=1
This will always return one row. It does however contain the 'dummy_id' column too. You can however just ignore that ofcourse and do with the (empty) data what ever you like.
So again, this is just a trick to do it with a SELECT statement. There's no default way to get this done.
SHOW COLUMNS FROM cf_pagetree_elements;
This will give a result set explaining the table structure. You can quite easily parse the result with PHP.
Another method is to query the infomrmation schema table:
SELECT column_name FROM information_schema.columns WHERE table_name='cf_pagetree_elements';
Not really recommended though!
You could try:
SELECT * FROM information_schema.columns
WHERE table_name = "cf_pagetree_elements"
Not sure about your specific PHP+PDO approach (there may be complications), but that's the standard way to fetch column headings (field names).
this will list the columns of ANY query for PDO drivers that support getColumMeta. I am using this with SQL server and works fine even on very complex queries with aliased tables, sub-queries and unions. Gives me columns even when results are zero
<?php
// just an example of an empty query.
$query =$PDOdb->query("SELECT * from something where 1=0; ");
for ($i=0; $i<$query->columnCount(); $i++) {
echo $query->getColumnMeta($i)['name']."<br />";
}
?>
Even without PDO in the way, the database won't return the structure without at least one row. You could do this and ignore the data row:
SELECT * FROM cf_pagetree_elements LIMIT 1;
Or you could simply
DESC cf_pagetree_elements;
and deal with one row per field.
WHERE 1=0 does not work for me. It always returns empty set.
The latest PDO for SQLSVR definitely works with get column meta.
Simply set up your statement and use this to get an array of useful information:
$stmt->execute();
$meta= array();
foreach(range(0, $stmt->columnCount() - 1) as $column_index)
{
array_push($meta,$stmt->getColumnMeta($column_index));
}
Complete solution for Oracle or MySQL
for any or some columns (my goal is to get arbitrary columns exactly as they are in DB regardless of case)
for any table (w or w/o rows)
$qr = <<<SQL
SELECT $cols
FROM (SELECT NULL FROM DUAL)
LEFT JOIN $able t ON 1 = 0
SQL;
$columns = array_keys($con->query($qr)->fetchAll(PDO::FETCH_ASSOC)[0]);
if($cols === "*") {
array_shift($columns);
}
YOu could use MetaData with;
$cols = mysql_query("SHOW COLUMNS FROM $tableName", $conn);