Im trying to join two tables together becouse 2 columns match and i need info from second table to display the content. When i pressing a link with ?p=1a i want content to show and this info i have on the second table but not the first one. Where table 1 and table 2 match on column Menu. I have shorten down on some code/table info becouse its not relevant for this problem. im then displaying the info with mysql_fetch_assoc.
TABLE 1
MENU | subtitle | firstname |info
info | contact
word | woord
TABLE 2
MENU | page |
info | 1a
word | 1b
My code:
if(isset($_GET['p'])){
$page = $_GET['p'];
$find = mysqli_query("SELECT * FROM testcheck, testdoc INNER JOIN testdoc ON testcheck.Menu = testdoc.MENU AND page='$page' ");
while($row = mysqli_fetch_assoc($find)){
$subtitle = $row['subtitle'];
$firstname = $row['firstname'];
echo $firstname
}
}
Problem is correct kinda now but only letters work fine but when i combine page='1a' for example everything stop works.
Your syntax for the join is wrong.
Use:
"SELECT * FROM testcheck
INNER JOIN testdoc ON testcheck.Menu = testdoc.MENU AND page='$page'
");
Read more about LEFT JOIN and RIGHT JOIN. In your case you would need RIGHT JOIN to get data that is in second table but not in first.
Like popovitsj suggested your syntax is also wrong.
Correct syntax:
SELECT * FROM testcheck
INNER JOIN testdoc ON testcheck.Menu = testdoc.Menu AND page='$page'
Also note that you are using MENU upper case which is not a problem on windows but will be a problem on unix, it will give you an error Column Not Found.
EDIT
If your table has column MENU then it should be fine.
Related
I stumbled upon a query that I have never done until now.
Before asking the question I looked for if another user had had the same need as me but nothing.
My goal is very simple:
having two tables:
collaboratori (collaborators)
invite (invitations)
I have to count how many invitations the collaborators have made.
table structure of collaboratori:
ID_Collaboratori | cod_manager
37 4675
150 6675
3 6575
table structure of inviti:
invite_id | invite_code_manager
37 6675
39 6575
40 4675
41 6675
if I execute the join obviously I access the two tables in this way:
$q_stats_prod_manager = $connessione->prepare("
SELECT * FROM invite
LEFT JOIN collaboratori
ON collaboratori.cod_manager = invite.invite_code_manager ");
$q_stats_prod_manager->execute();
$r_stats_prod_manager = $q_stats_prod_manager->get_result();
my need lies in showing in a table:
show me for each manager who has his cod_manager inside the inviti table, the number of times he sent them.
Name Surname Manager 1 | Number of invite: 200
Name Surname Manager 2 | Number of invite: 50
Name Surname Manager 3 | Number of invite: 10
not limiting myself to just one counter but also being able to access other table values like any join
I take the liberty of putting the answer that was partially written by another user, adding a detail and explanation for future users. The resolution query for this case is the same:
$q_stats_prod_manager = $connessione->prepare("
SELECT count(invite.invite_id)
/*name of what you want to call the result you will see in the while*/
AS result_count, /*you can call this value whatever you want*/
/*Start | Values of the tables you are interested in selecting*/
collaboratori.nome,
collaboratori.data_registrazione,
invite.invite_code_manager
/*End | Values of the tables you are interested in selecting*/
FROM collaboratori
LEFT JOIN invite
ON invite.invite_code_manager = collaboratori.cod_manager group by invite.invite_code_manager
");
$q_stats_prod_manager->execute();
$r_stats_prod_manager = $q_stats_prod_manager->get_result();
$count_invite_manager=mysqli_fetch_array($r_stats_prod_manager);
$number_of_invite_manager = $count_invite_manager[0];
Select the id of the table you want to count
Give a name you wish you want to name the counted result
Select the values of the tables on which you will perform the join you want to view
Join the tables
Show the result with while
Code while:
<?php while($rowstatspm = mysqli_fetch_assoc($r_stats_prod_manager)){ ?>
<!-- this is the fancy name you associated with your query when you wrote: AS nameofwhatyouwant -->
<?php echo $rowstatspm['result_count'] ;?>
<?php } ?>
You seem to want aggregation. I assume you want all rows for collaboratori, so that should be the first table for the LEFT JOIN:
SELECT c.cod_manager, COUNT(i.invite_code_manager)
FROM collaboratori c LEFT JOIN
invite i
ON c.cod_manager = i.invite_code_manager
GROUP BY c.cod_manager;
Your question doesn't describe where the name comes from. But those fields should be in both the SELECT and GROUP BY.
SELECT count(invite.invite_id),collaboratori.name FROM collaboratori
LEFT JOIN invite
ON invite.invite_code_manager = collaboratori.cod_manager group by invite.invite_code_manager
Actually found a lot of question like this before posting but doesn't find one related with "Codeigniter" so I don't know how to implement those answer with codeigniter.
My meta_key table
key_id | key_name | key_parent
------------------------------
.....1..firstname........1
.....2..lastname.........1
My users_meta table
meta_id | meta_user_id | meta_key_id |meta_value |
--------------------------------------------------
1.........1..............1............chuck......
When I run this query
$this->db->select("*");
$this->db->from("meta_key");
$this->db->join("users_meta", "users_meta.meta_key_id=meta_key.key_id","left");
$this->db->where('users_meta.meta_user_id', '1');
$query=$this->db->get();
return $query;
It always return me single rows ( that is the firstname rows )
Instead of "left" join I tried every option ( Options are: left, right, outer, inner, left outer, and right outer ) from the codeigniter reference page but it still return single rows.
How can I make it to return the "surname" rows as well ?
As you commented that following code works for you so here it is as answer
//just guess and try
$this->db->where('users_meta.meta_user_id = 1 OR users_meta.meta_key_id IS NULL');
I am just getting started in learning how to do INNER JOINS correctly and I can't think of the best/easiest way to do this.
I am building a url shortener and I am trying to build a query that will get all long_url.destination's matching a slug "test". One slug might point to multiple long_url.destination's(URL shuffling, GEO matching, etc...). So I need the slug to get all long_url.destination's with the same short_url.slug.
Before I was running another query to get the short_id from the slug, then running another query to select all rows in long_url that had a matching short_id.
I think it might be quicker if I use an inner join, but I am unsure how to properly set it up.
I want to get all destination columns in table long_url with only the slug data in short_url without having to run a separate query to get the short_id from the slug.
Table: short_url
Columns: short_id | slug | enabled | timestamp
example: 1 test 1 1323343922
Table: long_url
Columns: long_id | short_id | destination | geo | enabled | timestamp
example: 1 1 http://www.test.com US 1 132334922
example: 2 1 http://www.test.co.uk UK 1 132334922
I got this so far:
SELECT destination, geo FROM long_url INNER JOIN short_url
ON long_url.short_id = short_url.short_id WHERE enabled = 1;
function get_long_urls($slug) {
$query = "SELECT....";
$stmt = $db->prepare($query);
$stmt->execute(array(':slug' => $slug));
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
return (array) $results:
}
example $results = array(
'http://www.test.com' => 'US',
'http://www.test.co.uk' => 'UK',
);
Thanks for any help.
select long_url.destination
, long_url.geo
from long_url
inner
join short_url
on long_url.short_id = short_url.short_id
where short_url.slug = :slug
and long_url.enabled = 1
You don't need to qualify all column names like I did, because in this particular query there wasn't any ambiguity. All I really did is add a bound parameter placeholder.
SELECT destination, geo FROM long_url LEFT JOIN short_url
ON (long_url.short_id = short_url.short_id) WHERE enabled = 1
Lets see if I can explain this. I am displaying a table in PHP with up/downvote arrows. PHP calls a MySQL query to get the data, then places it in a table with a "while" loop. During this loop, I want to check and see if a user has already upvoted a row, and represent that with a different looking up arrow, etc. This is how I have gone about this so far.
If a user upvotes something, it is stored in a mysql db that looks something like this:
username| upvote| item_id
Bob | 1 | 2293
Bob | 1 | 2295
Sally | 1 | 2295
How do I tell php to check if "Bob" has a "1" on item "2293" in the middle of a while loop of a different MySQL array?
echo '<table>';
while ($row = mysqli_fetch_array($data)) {
echo '<tr>';
//insert php statement checking $row2 to see if Bob has upvoted the data in this row
//so I can place the appropriate arrow here
echo '</tr></table>';
}
What you need here is probably a MySQL join query. An example could be:
Your existing SQL:
SELECT * FROM `items`
We then join all rows from table "upvotes", but only those rows which the current user has placed:
The final SQL:
SELECT `items`.*, COUNT(`upvotes`.`item_id`) AS `upvotes` FROM `items` LEFT JOIN (`upvotes`) ON (`upvotes`.`username` = $currentUserName AND `items`.`id` = `upvotes`.`item_id`) GROUP BY `items`.`id`
Then you should be able to use the same PHP code, but now you can check if "$row['upvotes'] > 0".
I have 3 tables the subject, student, and relation
The following are sample data
students table
id name
1 John
2 Doe
3 Jane
subject table
id subject
1 Math
2 Science
3 English
relation table
id student_id subject_id
1 1 1
2 1 3
3 2 1
4 1 2
in this case sudent with id=1 has 3 subjects. How can I get result like this?
student name is John
subjects are:
Math
Science
English
I already get the values for student, what I'm trying to do is get his subject to be shown by user.
I'm totally confused using join tables. I'm a newbie in php and I start learning this last week. I'm getting an error on my code. Please help.
My Cuurent code is this:
<?php
//mysql connection
$query = "
SELECT *,* FROM relation, subject
on subject_id = id
WHERE student_id = $student_id
";
$result = mysql_query($query);
?>
Student name is <?php echo $name ?><br />
Subjects are:<br />
<?php
while($row = mysql_fetch_array($result)) {
echo $row["subject"];
}
?>
Start by making sure your query is right. I think this is what you're looking for:
SELECT subjects.*
FROM subjects,
INNER JOIN relations ON relations.subject_id = subjects.id
WHERE relations.student_id = $student_id
It might pay to check it in a mysql client first (e.g., phpMyAdmin). You'll notice in the SELECT part I only have subjects.* because that is all you need.
I actually ask an interview question to weed out people who don't have basic SQL knowledge but claim it on their resume that this is a direct implementation of. It can lead to a good conversation about database design, normalization, de-normalization etc.
What I'd want to see is the basic join syntax that goes hand in hand with the relationship table you've created.
"Select subject from subjects inner join relations on relations.subject_id = subjects.id where relations.student_id = ?".
Taking it the next step you get to
"Select subject from subjects inner join relations on relations.subject_id = subjects.id inner join students on relations.student_id = students.student_id where students.name = ?".
allowing you to query without pre-fetching the student id if you don't want to expose your internal database keys to the external user.
The question mark is for variable binding, its rare that its a reasonable practice to not escape inputs for database interactions. Variable binding for queries is an easy way to get good coverage on that issue.
I love asking this design problem as an interview question because it can quickly lead to discussions about SQL injection, how to sanitize web form input, and general best practices in data management, web application development and database design.
There's the GROUP_CONCAT() aggregate function for this situation:
SELECT students.id, students.name, GROUP_CONCAT(subject.subject) AS subjects
FROM students
LEFT JOIN relation ON students.id = relation.student_id
LEFT JOIN subject ON relation.subject_id = subject.id
GROUP BY students.id
ORDER BY students.name
which will return data like this:
+-------------+---------------+------------------------+
| students.id | students.name | subject.name |
+-------------+---------------+------------------------+
| 1 | John | Math, English, Science |
| 2 | Doe | Math |
| 3 | Jane | NULL |
+-------------+---------------+------------------------+
You can do this without the grouping, in which case you'll get one row for every id/student name/subject name, and then you can use a simple state machine like in OMG Ponies' answer for the display portion.
<?php
//mysql connection
function query($query){
global $conn;
$qu=mysqli_query($conn,$query);
return $qu;
}
$query1 =query("
SELECT * FROM student
WHERE student_id = $student_id
");
$query2=query("SELECT * FROM relation, subject
WHERE relation.student_id = $student_id
AND subject.id=relation.subject_id
");
$name=mysqli_fetch_assoc($query1);
?>
Student name is <?=$name['name']?><br />
Subjects are:<br />
<?php
while($row = mysql_fetch_array($query2)) {
$rew[]=$row['subject'];//For store subject
echo $row["subject"];
}
$subject=join(",",$rew);//Get the stored subject from array
?>
Maybe can help you ?
The simple way to do this, is to query all students:
SELECT * FROM `students`;
and then loop the resultset in php, now for each of the rows you have to make another query to get students subjects:
SELECT * FROM `subject` WHERE `id` IN (SELECT subject_id FROM relation WHERE student_id={$student_row['id']})
assuming $student_row is the name you choose for assigning fetched record.
Now, you do a nested-loop to fetch this query, and print students' subjects.