I have no idea with joins and I am really having a trouble getting the logic. Can anyone please help me?
Here is my table Announcements:
AnnouncementID Subject Header Status
---------------------------------------------------
1 Peter Header 2 Publish
2 2x2 Header 3 Draft
3 Resignation Header 4 Publish
And here is another table ReadAnnouncements:
AnnouncementID Username Status
---------------------------------------------
1 User 1 Read
2 User 2 Read
2 User 3 Read
I want my result to be
AnnouncementID Username Status Header Subject
---------------------------------------------------------------
1 User 1 Read Peter Header 2
2 User 2 Read 2x2 Header 3
2 User 3 Read 2x2 Header 3
Please teach me how I am really confused been trying this for two days already.
<?php
$sql=" SELECT a.AnnouncementID,a.Created,r.Username,a.Status,a.Header,a.Body from Announcements a join ReadAnnouncements r using(AnnouncementID) WHERE a.Status = 'Publish'";
$result = mysqli_query( $conn,$sql);
while($rows = mysqli_fetch_array($result)){
$time = date('h:i:s a',strtotime($rows['Created']));
$date = date('Y-m-d',strtotime($rows['Created']));
if($rows['ReadStatus'] == 'Unread'){
echo '
<tr class="'.$rows['Status'].'clickable-row" >
<strong><td class="view-message dont-show"><div>'.$rows['Header'].'</div></td>
<td class="view-message "><a href="ViewAnnouncement.php?view_id='.$rows['AnnouncementID'].'" style="text-decoration: none" class="text-dark" ><div>'.substr($rows['Body'],0,90).'</div></a></td>
<!--<td class="view-message inbox-small-cells"><i class="fa fa-paperclip"></i></td>-->
<td class="view-message text-right"><div><h6>'.$time.''.'<br>'.''.$date.'</h6></div></td></strong></tr>
';
}else{
echo '<strong>
<tr class="'.$rows['Status'].'clickable-row" >
<strong><td class="view-message dont-show"><div>'.$rows['Header'].'</div></td>
<td class="view-message "><a href="ViewAnnouncement.php?view_id='.$rows['AnnouncementID'].'" style="text-decoration: none" class="text-dark" ><div>'.substr($rows['Body'],0,90).'</div></a></td>
<!--<td class="view-message inbox-small-cells"><i class="fa fa-paperclip"></i></td>-->
<td class="view-message text-right"><div><h6>'.$time.''.'<br>'.''.$date.'</h6></div></td></strong></tr>
</strong>';
}
}
?>
I want to select all rows from table announcements that are only Published and classify them if they are read or unread based on username and announcement id.
You can use the below query to get the result.
select a.AnnouncementID,r.Username,r.Status,a.Header,a.Subject
from Announcements a
join ReadAnnouncements r on r.AnnouncementID=a.AnnouncementID
Joins are pretty easy, check this explanation.
In your case, you can do something like this:
SELECT A.AnnouncementID, A.Username, R.Status, A.Header, A.Subject FROM Announcements A join ReadAnnouncements R USING(AnnouncementID)
You can use inner join. The INNER JOIN keyword selects records that have matching values in both tables.
SELECT a.AnnouncementID,r.Username,r.Status,a.Header,a.Subject
from Announcements a
join ReadAnnouncements r using(AnnouncementID)
Use JOIN clause to combine rows from two or more tables in a database, based on a related column between them ( in your case, AnnouncementID ).
When combine data from 2 tables, you have a few combinations possible:
(INNER) JOIN: Returns records that have matching values in both tables
LEFT (OUTER) JOIN: Return all records from the left table, and the matched records from the right table
RIGHT (OUTER) JOIN: Return all records from the right table, and the matched records from the left table
FULL (OUTER) JOIN: Return all records when there is a match in either left or right table
(source: https://www.w3schools.com/sql/sql_join.asp)
Using your database schema, you should use:
select * from Announcements as A INNER JOIN ReadAnnouncements as RA ON A.AnnouncementID RA.AnnouncementID
You don't mention which DBMS you are using, so SQL query above may differ.
Related
This question already has answers here:
How to resolve ambiguous column names when retrieving results?
(11 answers)
Closed 2 years ago.
I have two tables like this:-
Tablea
-------
id|Comp_name|
1 |abc |
Tableb
--------
ids|id|Comp_name|
2 |1 |def|
I'm trying to inner join these two table into one with query like this
SELECT * FROM tablea
INNER JOIN tableb ON tablea.id=tableb.id
The result is like this
id|Comp_name|ids|Comp_name|
1 |abc |2 |def|
.
How To separate Comp_name value into php ?
I tried code like this but fail:-
foreach($query->result() as $row){
echo '<tr class="'.$class.'">
<td>
'.$row->Tablea.Comp_name.'
</td>
<td>
'.$row->Tablea.Comp_name.'
</td>
An alias can be used in a query select list to give a column a different name.
For more info Click here.
SQL Query looks like
SELECT tablea.id,tablea.Comp_name AS compname_a, tableb.*
FROM tablea
INNER JOIN tableb ON tablea.id=tableb.id
PHP
<?php foreach($query->result() as $row):?>
<tr class="<?php echo $class?>">
<td><?php echo $row->compname_a ?></td>
<td><?php echo $row->Comp_name ?></td>
</tr>
<?php endforeach;?>
For your desired output, you just need to use alias for getting same column name value from two tables.
Modified Query:
SELECT tablea.id, tablea.Comp_name as FirstVal,
tableb.ids, tableb.Comp_name as SecondVal
FROM tablea
INNER JOIN tableb ON tablea.id=tableb.id
Than you can get in php something like:
$row->FirstVal // for ist value
$row->SecondVal // for second value
You can also explore more: MYSQL Alias
You can try the following:
SELECT id, tablea.Comp_name as A_Comp_name, ids, tableb.Comp_name as B_Comp_name
FROM tablea
INNER JOIN tableb ON tablea.id=tableb.id
And the result will be something like this:
id|A_Comp_name|ids|B_Comp_name|
1 |abc |2 |def |
Use alias for this type of situation.
query:
SELECT tablea.Comp_name as company1, tableb.Comp_name as company2
FROM tablea
INNER JOIN tableb ON tablea.id=tableb.id
This question already has answers here:
How to resolve ambiguous column names when retrieving results?
(11 answers)
Closed 2 years ago.
I have two tables, one is projects, and the other is users.
PROJECTS table
ID | USER_ID | NAME
-------------------------------------
80 | 1 | ABC Co.
82 | 2 | XYZ Inc.
USERS table
ID | FIRSTNAME | LASTNAME
-------------------------------------
1 | Joe | Namath
2 | Jimmy | Fallon
What I want is to write a query such as:
SELECT * FROM PROJECTS, USERS WHERE PROJECTS.USER_ID=USERS.ID AND FIRSTNAME = "Joe"
I can successfully run the query in php, but when I attempt to access the results, I don't get what I want. I understand why, but I can't figure out a way to correct it. For example:
$row = mysqli_fetch_query($awesomeDatabaseLink);
echo $row['ID]; //returns '1' and I really wanted '80'
I get it. The two tables have fields with the same name, but it's not the same data. MySQL returns its best guess at what I so ambiguously asked for. However, I have also tried:
echo $row['PROJECTS.ID']; //returns an empty string.
I should mention that I desperately need "*" from both tables. The Projects table has dozens and dozens of fields (not my design, and re-engineering the database is out-of-scope). The Users table is also very extensive, so listing each field individually is much more impractical than it would appear by looking at my example tables.
Any suggestions?
SH
The quickest fix is to assign a unique column alias for the expression (in this case just a simple column reference).
When you do that, you will need to qualify the * with the table name or alias. If you want to return all of the columns from both tables, you will need to included a * for each table.
Also, ditch the old-school comma operator for the join operation, and use the JOIN keyword instead. And qualify all column references. For example:
SELECT PROJECTS.*
, USERS.*
, PROJECTS.ID AS MY_PROJECTS_ID
FROM PROJECTS
JOIN USERS
ON USERS.ID=PROJECTS.USER_ID
AND USERS.FIRSTNAME = "Joe"
The assigned alias MY_PROJECTS_ID will be the name of the column in the result set, so you reference that column by the assigned alias.
This assumes that there are no other columns being returned with the name MY_PROJECTS_ID.
Anytime there are two (or more) columns in the resultset that have the same name, you'll only get one of those columns referencing it by name.
I'd suggest you to use alias. That'd make things less ambiguous.
Try this:
SELECT
PROJECTS.ID AS project_id,
USER_ID,
NAME,
USERS.ID AS user_id,
FIRSTNAME,
LASTNAME
FROM PROJECTS, USERS
WHERE PROJECTS.USER_ID=USERS.ID AND FIRSTNAME = "Joe"
And then:
echo $row['project_id']; //returns Project id
Hope this helps.
When you select stuff from multiple tables you should always qualify the names (give the full path, like table.column). If two tables share a column name then you need to give them different names.
SELECT u.ID AS UserId,
u.FIRSTNAME AS FirstName,
u.LASTNAME AS LastName,
p.ID AS ProjectId,
p.NAME AS ProjectName
FROM USERS AS u
JOIN PROJECTS AS p ON p.USER_ID = u.ID
WHERE u.FIRSTNAME = "Joe"
If you want to get every column, but some of their names clash, then you can just rename the ones that clash, like so:
SELECT *,
u.ID as USERID,
p.ID as PROJECTID
FROM USERS AS u
JOIN PROJECTS AS p ON p.USER_ID = u.ID
WHERE u.FIRSTNAME = "Joe"
Hope this will help you.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Using single SQL</title>
<style>
table,td,th
{
padding:10px;
border-collapse:collapse;
font-family:Georgia, "Times New Roman", Times, serif;
border:solid #ddd 2px;
}
</style>
</head>
<body>
<table align="center" border="1" width="100%">
<tr>
<th>product id</th>
<th>product name</th>
<th>category name</th>
</tr>
<?php
mysql_connect("localhost","root");
mysql_select_db("dbtuts");
$res=mysql_query("SELECT c.* , p.* FROM tbl_categories c,tbl_products p WHERE c.cat_id=p.cat_id");
while($row=mysql_fetch_array($res))
{
?>
<tr>
<td><p><?php echo $row['product_id']; ?></p></td>
<td><p><?php echo $row['product_name']; ?></p></td>
<td><p><?php echo $row['cat_name']; ?></p></td>
</tr>
<?php
}
?>
</table>
</body>
</html>
follow this [link] (http://www.codingcage.com/2014/12/fetch-data-from-multiple-tables-in-php.html)!
I´m doing SQL to display actual subject which is teaching currently by this and this teacher. It should displays only name of subject(f.e. it displays 'languages' at 8am at Teacher´s profile). In database I have table - timetable and there are data of start_time and end_time which are saved in DATETIME. I have problem how to interconnect SQL and PHP and then display.
I have this SQL query:
SELECT lessons.schoolday, lessons.start_time, lessons.end_time, lectors.lectorsurname, studentgroups.class_id, classes.grade, subjects.subjectname
FROM lessons INNER JOIN lectors ON lessons.lector_id=lectors.lector_id
INNER JOIN studentgroups ON lessons.studentgroup_id=studentgroups.studentgroup_id
INNER JOIN classes ON studentgroups.class_id=classes.class_id
INNER JOIN subjects ON lessons.subject_id=subjects.subject_id
WHERE lessons.start_time <= substring(('".date('Y-m-d H:i:s')."'),11,6)
AND lessons.end_time >= substring(('".date('Y-m-d H:i:s')."'),11,6)
AND lectors.lector_id=:id");
When I change date instead of interval(f.e. start_time->0000-00-00 08:00:00, end_time->0000-00-00 08:45:00), it is working. But in this way, it prints only Array(). HTML is displaying with Latte template and there is condition, if empty array, it displays message=Teacher is not teaching currently, but this is also not working.
.......
php code:
$stmt3 = $db->prepare(" SELECT l.schoolday, l.start_time, l.end_time, t.lectorsurname, sg.class_id, c.grade, s.subjectname
FROM lessons l
INNER JOIN lectors t ON l.lector_id=t.lector_id
INNER JOIN studentgroups sg ON l.studentgroup_id=sg.studentgroup_id
INNER JOIN classes c ON sg.class_id=c.class_id
INNER JOIN subjects s ON l.subject_id=s.subject_id
WHERE l.start_time <= CURTIME() AND l.end_time >= CURTIME() AND t.lector_id=:id
ORDER By c.grade, l.schoolday, l.start_time");
$stmt3->bindValue(":id", intval($_GET["id"]));
$stmt3->execute();
$data=$stmt3->fetchAll();
print_r($data);
$tplVars["lesson"] = $stmt3->fetchAll();
and latte template
<table>
.
.
.
<tr>
<th> Aktuálne vyučuje: </th>
</tr>
{foreach $lesson as $aktual}
{if !empty($aktual['grade'])}
<tr>
<td>{$aktual['grade']} </td>
</tr>
{/if}
{if ($aktual['grade']) == NULL}
<tr> <td> <span> Učiteľ momentálne nevyučuje </span></td></tr>
{/if}
{/foreach}
</table>
Search for some examples. with some aliases its better readable. Is a NOW() not enough? see this link for more MySql date and time functions
SELECT l.schoolday, l.start_time, l.end_time, t.lectorsurname, sg.class_id, c.grade, s.subjectname
FROM lessons l
INNER JOIN lectors t ON l.lector_id=t.lector_id
INNER JOIN studentgroups sg ON l.studentgroup_id=sg.studentgroup_id
INNER JOIN classes c ON sg.class_id=c.class_id
INNER JOIN subjects s ON l.subject_id=s.subject_id
WHERE l.start_time <= NOW() AND l.end_time >= NOW() AND t.lector_id=:id
I have been trying to get some results when selecting combo boxes.
here is my query:
$strSQL = "SELECT * FROM studentresult,student where studentresult.studentid=student.id and student.class='$classes' and term='$term'and studentresult.studentid=student.id and year='$year' ";
This query is returning all the studentresult.id = 2 where studentresult.id is primary.
This is the php code:
<td><div align="center"><?=$objResult["id"];?></div></td>
<td><div align="center"><?=$objResult["studentid"];?></div></td>
<td><?=$objResult["subjectid"];?></td>
<td><?=$objResult["marks"];?></td>
<td><div align="center"><?=$objResult["term"];?></div></td>
<td align="right"><?=$objResult["year"];?></td>
<td align="right"><?=$objResult["rank"];?></td>
The id is taken from student table rather than being taken from studentresult table. Can someone help me with this.
EDIT 1:
The id is present in both tables
EDIT 2:
Student result:
id| StudentID| SubjectID| Marks| Rank| Term| Year
Student:
id| Roll Num| class| Name| Surname
Thanking You In Advance
Bhaamb
$strSQL = "SELECT *,studentresult.id as stid FROM studentresult,student where studentresult.studentid=student.id and student.class='$classes' and term='$term'and studentresult.studentid=student.id and year='$year' ";
Then
<div align="center"><?=$objResult["stid"];?></div>
You Better specify the column names instead of (*) from both the tables alias the column names to avoid column name conflicts if both are same and also try to use Join(Inner or Left) based on the need.
for example, some thing like this:
SELECT S.id AS student_id, SR.id as StudentResultId, S.class, s.year
FROM studentresult AS SR
INNER JOIN student AS S
WHERE SR.studentid=S.id and S.class='$classes' and s.term='$term'and SR.studentid=s.id and s.year='$year'
First of all, why do you use this twice in the where clause?
studentresult.studentid=student.id
Please define all needed columns explicitly while joining tables having the same column names, e.g.
SELECT studentresult.id as sr_id, student.id as s_id ... FROM ...
and change it in your php code:
<?=$objResult["sr_id"];?>
I have two cycles in PHP, that I needed converting to smarty structure. Down includes PHP code.
Code:
<pre>
$query = mysqli_query($cnn, "SELECT *, COUNT(*) AS ph FROM course INNER JOIN completed_course ON course.id = completed_course.id_course GROUP BY course.id");
while ($row = mysqli_fetch_array($query)){
<tr> <td> <?php echo $row['id']; ?></td><td> <?php echo $row['nazev']; ? </td><td>
?php echo $row['ph']; ? </td> <td>
?php
$Number_of_graduates = mysqli_query($cnn, "SELECT COUNT(*) AS abs FROM participant where id_completed_course = $row[id]");
while ($rAbs = mysqli_fetch_array($Number_of_graduates)){
echo $rAbs['abs'];
} ?
</td>
</pre>
The question is. How to convert the second loop where first id from SQL?
Ok, so your question is really about SQL. Let's look at your queries. The first one looks like this:
SELECT *, COUNT(*) AS ph
FROM course
INNER JOIN completed_course ON course.id = completed_course.id_kurz
GROUP BY course.id
I'm assuming (because I don't know anything about your database scheme) that this is going to give a list of courses and the number of students (maybe - I don't know what's in the completed_course table) who completed them. As written, this query is going to also give you some data from the completed_course table, but it's likely to be meaningless since you're grouping only on course.id.
The second query is:
SELECT COUNT(*) AS abs
FROM participant
WHERE id_completed_course = {DATA FROM FIRST QUERY}
Presumably, this query is intended to give you the total number of participants of completed courses. To make that work, the WHERE clause could look like this:
SELECT COUNT(*) AS abs
FROM participant
WHERE id_completed_course IN (
SELECT course.id FROM
FROM course
INNER JOIN completed_course ON course.id = completed_course.id_kurz
)
Notice that I'm taking the values selected in the first query and making them part of an IN clause. This query can be simplified significantly - for instance, the JOIN in the subquery is really only selected ID values from the completed_course table:
SELECT COUNT(*) AS abs
FROM participant
WHERE id_completed_course IN (
SELECT id_kurz
FROM completed_course
)
And the query will actually be more efficient if you get rid of the subquery altogether and just join the participants to the completed_course table.
SELECT COUNT(*) AS abs
FROM participant
INNER JOIN completed_course ON participant.id_completed_course=completed_course.id_kurz
This last query is going to give you one value: the number of participants whose id_completed_course value corresponds to an item in the completed_course table. You can use the mysqli methods to retrieve this data and pass it to your Smarty template.