small problem in mysql query? - php

i have small problem in my sql query
my tables
/* threads
thread_id/thread_title/thread_content
1 / any post title / welcome to my post
relations
cate_id/thread_id
1 / 1
2 / 1
categories
category_id/category_name
1 / some_cate
2 / second_cate
*/
My sql query
$q = mysql_query("SELECT t.*,c.*, GROUP_CONCAT(r.cate_id SEPARATOR ' ') as cate_id
FROM threads as t
LEFT JOIN relations as r on r.thread_id = t.thread_id
LEFT JOIN categories as c on c.category_id = r.cate_id
GROUP BY r.thread_id
");
php code
while($thread = mysql_fetch_array($q)){
echo 'Post title is: ' . $thread['thread_title'] . '<br />'; // work fine
echo 'Post content is: ' . $thread['thread_content'] . '<br />'; //work fine
echo 'Categories id is : ' . $thread['cate_id'] . '/' . '<br />'; // cate_id of relations table work fine
echo 'Categories names is : ' . $thread['category_name'] . '/'; // category name of categories table don't work fine
echo '-------End of first POOOOOOOOOOOST--------';
}
OUTPUT
/*
any post title
welcome to my post
1/2
some_cate/
-------End of first POOOOOOOOOOOST-------
*/
Now my problem is!
There is small problem in query
there is two categories id (1 and 2)
should be there is two categories name!
some_cate / second_cate
but it display only one! though it display two categories id!
categories names does not repeat
but the categories id is repeat! and working fine
##Doug Kress
i tryid your code but there is problem in your code with mysql_fetch_array
i got duplication of posts!
any post title
welcome to my post
some_cate/
any post title
welcome to my post
second_cate/
i am using CONCAT and GROUP BY to avoid this problem

The problem is actually in the GROuP BY - you're telling it to group by r.thread_id - based on your example, there's only one thread_id (1), so it will only return one record.
I'm guessing you don't need the GROUP BY or the GROUP_CONCAt at all.
SELECT t.thread_title, t.thread_content, r.cate, c.category_name
FROM threads as t
LEFT JOIN relations as r on r.thread_id = t.thread_id
LEFT JOIN categories as c on c.category_id = r.cate_id
It's usually best to specify all of the fields that you're going to use. Otherwise, it's unnecessary work for MySQL and for PHP, and it doesn't make your intent very clear.
I don't know the data, but based on your sample, you could change the LEFT join to an INNER join.

You must add GROUP_CONCAT(c.category_name, ' ') as category_name at your SELECT statement
If you will meet problem with same column name then just rename category_name to something else.

Related

php mysql three left join method

I have three table:
Article:
|id|title|timestamp|......
group_tags:
|id|content_id|tags_id
tags_name:
|id|name|
I need to list article title with any tag id:
function _tags_search_($id,$type){
$DB_QUERY = mySqli::f("SELECT title FROM " . ARTICLES . " LEFT JOIN " . POSTS_TAGS . " ON " . ARTICLES . ".id = " . POSTS_TAGS . ".content_id WHERE
" .POSTS_TAGS . ".tags_id = ? AND approved = 1 ORDER BY timestamp DESC LIMIT 12", $id);
foreach($DB_QUERY as $row){
$data[] = $row;
}
return $data;
}
this worked for me and show list of article title.
But I need to show tag name for tags id in addition to list title like this:
Search result for : Linux
I have two way :
three left join method ( if true how do?)
fetch another query for show tag name.
I think three join is better and faster. how do show tags name with three join method?!
try this
SELECT title, name from
group_tags g
INNER JOIN article ON a.id = g.content_id
INNER JOIN tags_name t ON t.id = g.tags_id
Let me know if you face any issue

show result from percentage

Hello I have I field in my table called percentage but what I looking to do is only show a result based on percentage ie if I set 10 it would only show the result 10% of the time.
here is my database which is Joomla database code in mysql
// Select the required fields from the table.
$query->select(
'a.id, a.title, a.simulator, a.generation, a.quality, a.quantity, a.percentage, a.attribute, a.checked_out, a.checked_out_time, a.catid' .
', a.state, a.access, a.created, a.created_by, a.version, a.ordering'
);
$query->from('#__evolutionary_texture AS a');
// Join over the users for the checked out user.
$query->select('uc.name AS editor')
->join('LEFT', '#__users AS uc ON uc.id=a.checked_out');
// Join over the asset groups.
$query->select('ag.title AS access_level')
->join('LEFT', '#__viewlevels AS ag ON ag.id = a.access');
// Join over the species.
$query->select('category.title AS category_title')
->join('LEFT', '#__categories AS category ON category.id = a.catid');
$query->select('parent.title AS parent_title')
->join('left', '#__categories AS parent ON parent.id=category.parent_id');
// Join over the section.
//$query->select('section.title AS section_title')
// ->join('LEFT', '#__categories AS section ON section.id = a.catid');
// Join over the users for the author.
$query->select('ua.name AS author_name')
->join('LEFT', '#__users AS ua ON ua.id = a.created_by');
$query->where('parent.title = ' . $db->quote($species));
//echo "section = $section";
$query->where('category.title = ' . $db->quote($section));
// check where generation.
$query->where('a.generation = ' . $db->quote($generation));
// check where simulator.
$query->where('a.simulator = ' . $db->quote($simulator));
// Debug the query
//var_dump($db->replacePrefix( (string) $query ) );
// Set the query and load the result.
$db->setQuery($query);
as what I trying to do is only show texture based on the percentage as this data is imported into a game called second life
my percentage field right now goes from 0 - 100
After analyzing your code/problem, I can suggest following.
you need to store a variable random_no and times somewhere, in SESSION, DATABSE or APPLIATION level var
The value of random_no will be =array() of 100 int values from 1 to 100 randomly// example =array(23,15,67,98, ...., 5); // all 1-100 numbers once only
value of times will be 0 initially and will increase by 1 after each query. When value reach to 99 then next it will be 0 and recalculate the value of random_no. //code at where are querying database
Now run your query with condition: a.percentage >= $random_no[$times]
creating $randome_no array:
$random_no=array();
for($i=1;$i<=100;i++){
$random_no[]=$i;
}
shuffle($random_no);
PHP shuffle
Above method will select records percentage times randomly

How can I combine 2 seperate MySQL queries in a foreach statement

Say I have some posts and those posts contain comments, some posts have more than 1 comment and others have only 1 comment.
I would have to grab all the data from the user from that post and the user info from the person who commented on that post. Now say i have to echo out all that data. I would first go with a foreach and another foreach inside sorta like this!
So I made 2 MySQL queries $postinfo containing all userinfo for the post and the second MySQL query $comments containing all the comments for each post.
Now this works but I was wondering if there is a better way, better practice? The reason I want to fix this, is because I want to AJAX the comments so they can auto update and this way seems to sluggish
<?php
foreach ($postinfo as $info) {
echo "<div id='container'>
<div id='userpost'>
<p>" . $info['firstn'] . "</p>
<p>" . $info['posttext'] . "</p>
</div>";
foreach ($comments as $comment) {
echo "<div id='comments'>
<p>' . $comment['firstn'] . '</p>
<p>' . $comment['commenttext'] . '</p>
</div>"
}
echo "</div>";
}
?>
This query is running inside the foreach to fetch the comment for a particular post.
$comments = regular_query(
"SELECT a.from_who, a.dateposted, a.topostid, a.commenttext, b.firstn
FROM postcomments a
INNER JOIN users b ON a.from_who = b.id
WHERE a.topostid = :postid",
["postid" => $post_idr], $conn);
This one is outside the foreach:
$postinfo = regular_query(
"SELECT b.id, b.from_user, b.dateadded, b.posttype, b.posttext, b.photoname, d.firstn, d.lastn, e.status
FROM board b
INNER JOIN userprofiles c
INNER JOIN users d
INNER JOIN friendship e
ON b.from_user = c.user_id
AND b.from_user = d.id
AND e.friend_ids = b.from_user
WHERE e.status = 'Friend'
AND e.user_ids = :id
ORDER BY b.id DESC",
["id" => (int)$user_id], $conn);
Process One:
You can use one single query to get the one post and all its comment. But it has one problem For example One post have 20 comments so it will get post data 20 times
Query:
Select post.* form post join comment on post.postId=comment.postId where post.postId='your specific post id'
[You may have to change the query a lil bit or there may be some typo as i don't check it on tables]
Process Two:
Have two variable one is dic another is array
Post data will be in dictionary it will have one element with in it it will have comment array
$postData={
postId:1,
comment:({commentId:1,comment:"bla bla bla"},
{commentId:2,comment:"bla bla bla"}),
post:"bla bla post"
}
For post you have to run
Select * from post where postId=your specific id
And for comment
Select * from comment where postId=your specific id
As simple as that
Edit:
for(int i=0;i<postResult.count;i++)
{
if(i==0)
{
Print Your Post Info//so your post info will be echoed once
}
Print Your comment info//all your comment will be echoed here if any
}
Select postId,postTitle,postDesc,postedBy,postedAt,
commentId,commentTitle,commentDesc,commentedBy,commentedAt
from postTable JOIN commentTable ON postTable.postId = commentTable.postId
WHERE postTable.postId = 1 ORDER BY commentTable.postId DESC;
Iterate the Data like this :
{posts:[
{postId:1,postTitle:"title",postDesc:"desc",comments:[{comment1},{comment2}]},
{postId:2,postTitle:"title",postDesc:"desc",comments:[{comment1},{comment2}]}
{postId:3,postTitle:"title",postDesc:"desc",comments:[{comment1},{comment2}]}
]
}
Iterate the data using foreach
foreach($posts as $post){
foreach($comments as $comment){
}
}

While loop displaying result 3 times

Basicly I'm trying to make a simple news feed but I'm stuck at the moment as my while loop display the result 3 times, why is this? :/
<?php
$sql ="SELECT
*
FROM
news,
admins";
$result = mysql_query($sql);
if(!$result)
{
echo 'Error while selecting from database. Please contact the administration team';
} else {
while($row = mysql_fetch_assoc($result))
{
echo '
<div class="content_news">
<h1>' . $row['news_name'] . '</h1>
<p style="font-size:12px;">Posted by <b>' . $row['admin_name'] . '</b> on ' . $row['news_date'] . '
<p>' . $row['news_description'] . '</p>
read more
</div>
';
}
}
?>
If you'd like to see what I am talking about: http://freewallpaperblog.com/freshrp/
Ignore the last 2(those are static html not php)
your query selects data from 2 tables (news, admins) so it joins every row of 1st table with every row of 2nd table
SELECT * FROM news, admins
i recommend you to use following query
SELECT news.*, admins.admin_name FROM news
INNER JOIN admins ON news.admin_id = admins.id
where admin_id is your correct column name
You either have 3 admins or 3 rows of news. Your query makes a direct multiplication between tables. Try "left join" instead...
SELECT * FROM news
INNER JOIN admins ON admins.id = news.adminid
Or whatever adminid is in the news table.
Try the following query:
SELECT
*
FROM
news
Inner join admins on news.admin_id = admins.id
You made no JOIN statement in your SQL, as someone else has already commented on in your question. It would help if you posted the associated fields you're grabbing, but based on your $row keys, my best guess is the following should work for you (but I can't promise it will without knowing how your database is designed, I can only infer from the variable names):
$sql = "SELECT news.name, news.date, news.description, news.link, admins.name"
. "FROM news"
. "INNER JOIN admins"
. "ON news.name=admins.name"
References:
http://www.w3schools.com/sql/sql_join_inner.asp
http://www.w3schools.com/sql/sql_join_left.asp
http://dev.mysql.com/doc/refman/5.0/en/join.html

Mysql inner join query gives a row three times

Thanks for reading.
I'm trying to learn inner join and join. My aim is to comparing that if the user created the community is also marked as an admin in the CommunityMembers table (I'm not sure if INNER JOIN achieves this) and take all other community information from Community table related to CommunityID (this is possible with inner join as I understand).
I have two tables called Community and CommunityMembers.
the structure is for Community(it has other data such as date, contents etc...):
CommunityID - Slug - CreatedByUser
1 - video - 2
2 - funny - 2
3 - picture - 4
for CommunityMembers
CmID - UserID - Slug - Power
1 - 2 - video - admin
2 - 2 - funny - admin
3 - 4 - picture - admin
my php code: ( $_SESSION['UserID'] is 2 )
<?php
$sql = $dbc->prepare(" SELECT cm.*, com.*
FROM Community com
INNER JOIN CommunityMembers cm ON cm.UserID = com.CreatedByUser
WHERE cm.UserID = '" . $_SESSION['UserID'] . "'");
$sql->execute();
if($sql->rowCount()){
echo $sql->rowCount();
while($data = $sql->fetch()){
$output .= $data['Slug'] .'<br />';
}
echo $output;
}else{
$_ERROR = "no record";
}
?>
echo $output; prints
video
video
video
funny
funny
funny
and echo $sql->rowcount(); prints
6
Could you please help with this? Why is this printing same thing 3 times? and is my solution right to check if is user created the community is marked as admin in the CommunityMembers or do I need to check it?
Thanks.
Try this
$sql = $dbc->prepare("
SELECT cm.*, com.*
FROM Community com
INNER JOIN CommunityMembers cm ON cm.UserID = com.CreatedByUser
WHERE cm.UserID = '" . $_SESSION['UserID'] . "'
GROUP BY com.CreatedByUser
");
$sql = $dbc->prepare(" SELECT DISTINCT cm.*, com.*
FROM Community com
INNER JOIN CommunityMembers cm ON cm.UserID = com.CreatedByUser
WHERE cm.UserID = '" . $_SESSION['UserID'] . "'");
SELECT DISTINCT
http://dev.mysql.com/doc/refman/5.0/en/distinct-optimization.html
If all you need to know if its admin, don't bring all fields from CommunityMembers. Try this
$sql = $dbc->prepare(" SELECT DISTINCT cm.Power, com.*
FROM Community com
LEFT JOIN CommunityMembers cm ON cm.UseriID=com.CreaterByUser
WHERE cm.UserID = '" . $_SESSION['UserID'] . "'");
Didn't test it, but this should work even without DISTINCT.
If you select the 2 tables result SELECT cm.*, com.* it will return all differents couples so try to select only specifics fields you need.
PS : What is the full result, I mean not only the field slug ?

Categories