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
Related
I'm trying to display data from two different mysql tables on my website using php.
My aim is to display a match schedule with information from two tables. The first one includes all the teams plus their ID, the second includes all details on the games. I now want to "replace" the "home_id" and "away_id" fields with the respective team names from the first table.
The tables look as follows:
table "teams"
id name
-----------
1 Team 1
2 Team 2
3 Team 3
4 Team 4
...
table "matchschedule"
id home_id away_id goals_home goals_away date
1 1 2 0 2 2016-05-05
2 3 4 2 1 2016-05-06
...
With the following query I'm getting the required data within phpmyadmin:
SELECT
date, home.name, sp.goals_home, away.name, sp.goals_away
FROM
matchschedule sp
INNER JOIN
teams home on sp.home = home.id
LEFT JOIN
teams away on sp.away = away.id
However, when I implement this query into my website and add the code below to display the data the fields "home.name" and "away.name" are always empty. What do I need to change in order to get the team names displayed?
while($row = mysql_fetch_array($query)) {
?>
<table border=1>
<tr>
<?php
echo "<td>".$row['date']."</td>";
echo "<td>".$row['home.name']."</td>";
echo "<td>".$row['goals_home']."</td>";
echo "<td>".$row['away.name']."</td>";
echo "<td>".$row['goals_away']."</td>";
?>
</tr>
</table>
Final result (with missing info for both team names):
2016-05-05 [] 0 [] 2
2016-05-06 [] 2 [] 1
The issue is that when in query you request home.name mysql return to php column with title name and you can not reach that column using home.name anymore. And same for away.name.
That's why you need to set proper name for returned columns.
Change your query to:
SELECT
date, home.name home_name, sp.goals_home, away.name away_name, sp.goals_away
FROM
matchschedule sp
INNER JOIN
teams home on sp.home = home.id
LEFT JOIN
teams away on sp.away = away.id
and call those columns in php like:
echo "<td>".$row['date']."</td>";
echo "<td>".$row['home_name']."</td>";
echo "<td>".$row['goals_home']."</td>";
echo "<td>".$row['away_name']."</td>";
echo "<td>".$row['goals_away']."</td>";
Based on your table strcture, you should do the following :
SELECT
date, home.name AS homeName, sp.goals_home, away.name AS awayName, sp.goals_away
FROM
matchschedule sp
INNER JOIN
teams home on sp.home_id = home.id
LEFT JOIN
teams away on sp.away_id = away.id
So basically replace sp.home by sp.home_id and sp.away by sp.away_id and change the fields name as you have the same fields name in your tables.
I've 4 table for a newsletter. Newsletters, Subscribers, Subscriber Groups and Selected Subscriber Groups. I've choose subscriber groups in campaign edit area, and its save selected groups to tbl_newsletter_groups table like;
tbl_newsletters
NID title details
1 text 1 content 1
2 text 2 content 2
tbl_subscriber_groups
GID group_name
5 group 1
6 group 2
tbl_subscribers
SID GID email name
10 5 sub1#mail.com sub1 name
11 6 sub1#mail.com sub1 name
tbl_newsletter_groups
NGID NID GID
15 1 6
16 1 6
17 1 6
I want to show total selected subscriber count when I list newsletters in my page. My soulution works fine, Im looking for simple and clearly statement, there any faster way available like in single newsletter list statement?
Here my own count style (yes I know its too bad and long way);
$subGID = array();
$list = $myconn->query("SELECT * FROM tbl_newsletters");
while($listRs = $list->fetch_assoc()){
$grps = $myconn->query("SELECT * FROM tbl_newsletter_groups WHERE NID=". $listRs['NID'] ."");
while($grpsRs = $grps->fetch_asscoc()){
$subGID[] = $grpsRs['GID'];
} $grps->free();
$subs = implode(" OR GID=",$subGID);
$count = mysqli_num_rows($myconn->query("SELECT ID FROM tbl_subscribers WHERE GID=". $subs));
echo('Total Selected Subscriber: '.$count);
} $list->free();
Thanks.
The search term you want is "set-based logic".
Your thinking is sound: you need everything from tbl_newsletters, then you need to count results from tbl_subscribers, but in order to get those you need information from tbl_newsletter_groups.
In SQL, that's an indication you want a join. You've already discovered the conditions you need, you just don't know the syntax. A reference manual can help there.
Now you'll have a bunch of records, which you need to smash into a smaller number of records. You need aggregation functions and a GROUP BY clause.
So here's the final query:
SELECT n.NID, n.title, n.details, COUNT(s.SID)
FROM tbl_newsletters AS n
JOIN tbl_newsletter_groups AS g ON n.NID = g.NID
JOIN tbl_subscribers AS s ON g.GID = s.GID
GROUP BY n.NID
I've got two tables:
content:
id access
1 3
2 5
3 9
viewlevels:
id group
1 [10,12,15]
2 [8,12,11]
3 [9,10,5]
The access field in content is related with the id field in viewlevels.
I select the rows in viewlevels depending on the current user group. So for example, if group is = 10, my query will select rows 1 and 3. If the group is 12, it will select rows 1 and 2, etc. I'm using the following query:
$query="SELECT id FROM #__viewlevels WHERE rules LIKE '%$group%'";
My challenge is to count the number of rows for column id in table content where the access matches with the selected id's from the above query on table viewlevels.
I tried the following code but it is returning the error: undefined variable: nartigos
$query="SELECT count(id) FROM #__content WHERE access IN (SELECT id FROM #__viewlevels WHERE rules LIKE '%$group%')";
if ($stmt = mysqli_prepare($link, $query)) {
/* execute query */
mysqli_stmt_execute($stmt);
/* store result */
mysqli_stmt_store_result($stmt);
$nartigos=mysqli_stmt_num_rows($stmt);
/* close statement */
mysqli_stmt_close($stmt);
};
echo "Nº de artigos " .$nartigos;
First of all, you really should normalize your data. Consider having a many-to-many join table for viewLevels instead of having all groups in one row. That might look like this:
access_id group_id
1 10
1 12
1 15
2 8
2 11
2 12
3 5
3 9
3 10
That would make your query as simple as
SELECT c.id AS `content_id`, COUNT(v.access_id) AS `content_count`
FROM content AS c INNER JOIN viewLevels AS v
ON c.access_id = v.access_id
WHERE v.group_id = ?
GROUP BY c.id
Here ? is the group id you are querying against.
Without normalization (which again I STRONGLY recommend you do), you would still use a join, but it would look like this:
SELECT c.id AS `content_id`, COUNT(v.access_id) AS `content_count`
FROM content AS c INNER JOIN viewLevels AS v
ON c.access_id = v.access_id
WHERE v.group LIKE '%?%'
GROUP BY c.id
you need to "join" your tables.
the sql command cant query two tables seperately.
when you "join" 2 tables in your sql, think of it as making one virtual/temporary table in the air, of the 2 tables which you can then query.
this is quite a good intro http://www.sitepoint.com/understanding-sql-joins-mysql-database/
I am doing a web-based application in php for my university and I need to show how many students are taking some courses at the same time so they can avoid scheduling conflicts.
This my schema:
studentID course grade program
324532 csc232 0 computer science
I am using php and this is the SQL query. I put grade 0 because he/she taking the course right now.
$result = mysql_query("SELECT s1.course AS c1 , s2.course AS c2 ,count(*) AS count
FROM student s1 ,student s2
WHERE s1.studentID = s2.studentID
AND s1.course!=s2.course AND s1.grade='0' AND s2.grade='0' GROUP BY s1.course,s2.course");
The answer I got is like this:
cscs321 csci322 6 // there is 6 students taking this two courses together
csci321 csci113 4 // there is 4 students taking these two subjects together
The problem is that I got some repeated results. For example csci321, csc322
is the same as csci322 and csci321.
How can I avoid this repetition?
You could try this one:
SELECT
s1.course AS c1,
s2.course AS c2,
count(s2.studentID) AS count
FROM student s1
JOIN student s2 ON (
s1.studentID = s2.studentID
AND s1.course<s2.course -- <-- this line is important
AND s1.grade='0'
AND s2.grade='0'
)
GROUP BY
s1.course,
s2.course;
The idea is to "sort" the courses per line, so that
csci321, csc322
and
csc322, csci321
are considered the same, because csc233 < csci321
You should use SUM instead of COUNT because you want the sum of students and not the count.
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.