My query mixes up with arrays on execution - php

Right, hello.
I've been working on a website template and I've coded a forum-like section, but simply discussion threads, and now, I'm having struggles with a specific query. This.
SELECT * FROM cms_discussions d JOIN cms_discussions_comments c ON d.id = c.discussionid ORDER BY c.time DESC LIMIT 10
I thought it would be easy enough to see how others have their question answered on how to order one table by another table's row. So I tried their method, but now it's mixing it up with each other. This is how it used to look like when I was sorting the threads by their IDs
SELECT * FROM cms_discussions ORDER BY id DESC LIMIT 10
And this is how it looked.
While using the SQL query I first provided, the outcome came out kinda wrong. The author of the thread was changed to 'server' (which was the author field from cms_discussions_comments), so basically, the 'author' field from cms_discussion gets replaced with the 'author' field from cms_discussions_comments. How I display the threads are quite simply.
<?php
$response = $databaseHandle->query("SELECT * FROM cms_discussions d JOIN cms_discussions_comments c ON d.id = c.discussionid ORDER BY c.time DESC LIMIT 10");
while($row = $response->fetch_assoc()) {
stripslashes_array($row);
?>
<table class="row" onclick="window.location.href = '/discussion/<?php echo $row["id"]; ?>/';">
<tr>
<td style="width: 50px"><img src="/styles/<?php echo $styleConfig["theme"]; ?>/album/discussions/<?php echo ($row["active"] == 1)?("status_info"):("status_locked"); ?>.png"></td>
<td><p id="title"><?php echo $row["title"]; ?></p><br><p id="description">Posted <?php echo date("F j, Y, g:i A", $row["posted"]); ?> by <i><?php echo $row["author"]; ?></i>.</p></td>
</tr>
</table>
<?php } ?>
<?php } ?>
I'm really not sure what the issue is here since I usually just do basic queries. Thanks in advance for any assistance.
Edit: Forgot to provide the second screenshot:

Since your two tables cms_discussions and cms_discussions_comments both contain an author field, one of the twos is not going to be accessible in your result array if you just do SELECT *.
What you need to do is to explicitly select fields and assign aliases so that there is no overlaps.
You could do something like:
SELECT d.*, c.author AS comment_author FROM cms_discussions d JOIN cms_discussions_comments c ON d.id = c.discussionid ORDER BY c.time DESC LIMIT 10
With that query, your $row['author'] would refer to the field of cms_discussions while $row['comment_author'] would refer to the field of cms_comments. That being said, you might want to do the same for other fields like id.
If you simply do not want to select columns from cms_discussions_comments then this will do the trick:
SELECT d.* FROM cms_discussions d JOIN cms_discussions_comments c ON d.id = c.discussionid ORDER BY c.time DESC LIMIT 10

Related

Join Two MySQL Table and Display Result in Table

I have two table called t_user and t_chat. I am trying to display message from t_chat in PHP table like below.
$quotes_qry="SELECT * FROM t_chat ORDER BY id DESC LIMIT $start, $limit";
$result=mysqli_query($mysqli,$quotes_qry);
<?php
$i=0;
while($row=mysqli_fetch_array($result))
{
?>
<tr>
<td><?php echo ++$sr+$start;?></td>
<td><?php echo $row['sender'];?></td>
<td><?php echo nl2br($row['receiver']);?></td>
<td><?php echo nl2br($row['message']);?></td>
<td><?php echo time_elapsed_string($row['time']);?></td>
<td><img src="images/delete-icon.png"></td>
</tr>
<?php
$i++;
}
?>
I want display sender and receiver name which is located in table called t_user with username column. I am new in PHP and confused how can I achieve it. Let me know if someone can help me for achieve my task. Thanks a lot!
Note : t_chat table have userid witch column name called sender and receiver, currently I am displaying that userid in above table, instead I want display username.
Thanks
The joins might look something like this:
SELECT t_chat.sender AS 'sender', t_chat.receiver AS 'receiver', t_chat.message AS 'message', t_chat.time AS 'time', t_chat.id AS 'id', user1.username AS 'senderusername', user2.username AS 'receiverusername'
FROM t_chat
LEFT JOIN t_user AS user1 ON t_chat.sender = user1.id
LEFT JOIN t_user AS user2 ON t_chat.receiver = user2.id
ORDER BY id DESC
In this example I am joining the tables twice (as user1 and user2) so that the t_user table gets referenced independently for each lookup.
I also gave each column a name using AS to make them easier to reference later in your code.
Try this sql (The t_user table must have an id column that matches the userid from t_chat):
$quotes_qry="SELECT t1.sender, t1.receiver, t1.message, t1.time, t2.username FROM t_chat AS t1 INNER JOIN t_user AS t2 ON t1.userid=t2.id ORDER BY t1.id DESC LIMIT $start, $limit";
More details and examples about MySQL JOIN you can find in the tutorial from:
https://coursesweb.net/php-mysql/mysql-inner-left-join-right-join_t

Subquery executes more than one row and my query is different

SELECT enquiry.*,
(SELECT comm
from comments
where enquiry.id = comments.enquiryId
order by time DESC
) as comm
FROM enquiry
where id='110' AND cmpId='3'
when i want to execute more than one row by removing limit it say "subquery executes more than one row"
Please help
Your subquery is called a scalar subquery, meaning that it must have one column and at most one row. One simple method is to put the results in multiple rows, using JOIN:
SELECT e.*, c.comments
FROM enquiry e JOIN
comments c
ON e.id = c.enquiryId
where e.id = 110 AND e.cmpId = 3;
Or you can put the subquery in the from clause (as below), which is similar to join condition.
SELECT enquiry.*, comm.comm
FROM enquiry,
(SELECT comm
from comments
where enquiry.id = comments.enquiryId
order by time DESC
) as comm
where id='110' AND cmpId='3'
As the relation between enquiry & comments is 1 to many (as appears)
You need to add GROUP_CONCAT() functions to group all comments as follows:
SELECT enquiry.*,
(SELECT GROUP_CONCAT(comm)
from comments
where enquiry.id = comments.enquiryId
order by time DESC
) as comm
FROM enquiry
where id='110' AND cmpId='3'

How do I form an SQL query using DATE_SUB to retrieve and post yesterday's data?

Here's my query:
$sql = $db->Query("SELECT a.uid, SUM(a.today_clicks) AS clicks, b.login FROM user_clicks a LEFT JOIN users b ON b.id = a.uid WHERE b.login != '' GROUP BY a.uid ORDER BY clicks DESC LIMIT 3");
Here's the code i'm using for getting the top 3 users for today:
<tr><?
$tops = $db->FetchArrayAll($sql);
foreach($tops as $top){
echo '<td>'.$top['login'].'</td>';
}
?></tr>
Which gives me the top 3 user names with the most clicks for today.
Here's my table structure:
Table name :"user_clicks"
6 fields
uid
module
total_clicks
today_clicks
max_clicks
daily_clicks
How can i get the same data but just from a day before?
Thanks in advance!
Here is one generic way to filter the columns with a date corresponding to yesterday:
SELECT
*
FROM
mytable a
WHERE
DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 DAY), "Y-m-d") = DATE_FORMAT(a.date, "Y-m-d")
There is not enough information about your table structure to say how you would apply it in you case. So you will have to figure it out :)

Converting two loops to smarty

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.

Mysql count with descending with join and where clause ,two tables, limit?

Here i have implemented two tables (pages, pagestatistics).I need result for last five records using join from the those tables and also i need a count of cID field from second table (pagestatistics), i need that count result will be display in descending.
NOTE : Primary id is cID.
![pagestatistics][1]![pages][2]
<?php
$recentpageviews =mysql_query("SELECT Distinct(cID) FROM `pagestatistics` order by `pstID` desc limit 0,5");
$downloads=mysql_num_rows($recentpageviews);
$k=1;
$cid="";
while($views_values=mysql_fetch_array($recentpageviews))
{
$cid.=",".$views_values['cID'];
$k++;}
}
$explode =explode(",",$cid);
for($i=1;$i<count($explode);$i++)
{
$sql=mysql_query("select Distinct(a.cID),count(a.cID) as clicks,b.cFilename,a.date from pagestatistics as a left join pages as b on a.cID=b.cID where a.cID='".$explode[$i]."' order by a.cID desc");
$res=mysql_fetch_array($sql);
?>
<tr>
<td class='ccm-site-statistics-downloads-title'><?php echo $res['cFilename'];?></td>
<td class='ccm-site-statistics-downloads-title'><?php echo $res['clicks'];?></td>
<td class='ccm-site-statistics-downloads-title'><?php echo $res['date'];?></td>
</tr>
<?php }?>
How to display all records in descending order.
Thank in advance.
You can do it in this way just order by with your count separated with , in ORDER BY clause
$sql=mysql_query("select Distinct(a.cID),count(a.cID) as clicks,b.cFilename,a.date
from pagestatistics as a left join pages as b on a.cID=b.cID
where a.cID='".$explode[$i]."' order by a.cID,clicks desc");

Categories