Counting occurrences using Toxi solution - php

I'm new to mysql.
I wanted to develop a simple tagging system for my blog and came across this "Toxi" Solution of making 3 tables.
So, I have 3 tables:
`blog` containing `id` and `title`.
`blog_tags` containing `id` and `tags_id` and `blog_id`.
`tags` containing `id` and `name`.
tags_id is connected to Internal Relation to id in tags table.
Similarly, blog_id is connected to Internal Relation to id in blog table.
So, when in my function (where I get the array of all tags pertaining to a single blog) I execute a query for example (passing blog id as the parameter in the function),
$result = mysql_query("SELECT tags_id FROM blog_tags WHERE blog_id = '".$id."'");
$tags = array();
if($result === FALSE) {
die(mysql_error()); // TODO: better error handling
}
while($row = mysql_fetch_assoc($result)) {
$tags[] = I don't know what should come over here?
}
return $tags;
Or is there any other way to execute queries in this Toxi implementation?

UPDATED You need a simple JOIN. Your query should look like
SELECT bt.tags_id, t.name
FROM blog_tags bt JOIN tags t
ON bt.tags_id = t.id
WHERE bt.blog_id = n -- < n is an id of a blog
Here is SQLFiddle demo.
Now php is pretty straightforward
$sql = "SELECT bt.tags_id, t.name
FROM blog_tags bt JOIN tags t
ON bt.tags_id = t.id
WHERE bt.blog_id = $id";
$result = mysql_query($sql);
if($result === FALSE) {
die(mysql_error()); // TODO: better error handling
}
$tags = array();
while($row = mysql_fetch_assoc($result)) {
$tags[] = $row['name'];
}
...
On a side note: switch to PDO or mysqli. mysql_* extension is deprecated. In PDO you can use a syntactic sugar fetchAll(). And more importantly learn to use prepared statements. Right now your code is vulnerable to sql-injections.

Related

php loop start over when num_rows==0

I'm trying to write a php code to select form tables:
books
images
Some books does not have an image, so I want to skip it and select another book.
I have wrote this code but it does not work with me perfectly.
Now I'm getting only 5 records! it must be 6 as I limited in the book select query.
$slider_sql = "select * from books limit 6";
$slider_result = $conn->query($slider_sql);
while($slider_row = $slider_result->fetch_assoc()) {
extract($slider_row);
$img_sql = "SELECT big_img FROM images WHERE book_id = '$id'";
$img_rs = $conn->query($img_sql);
$img_row = $img_rs->fetch_assoc();
if ($img_rs->num_rows == 0)
continue; //--> here I want to start while again to select another book.
echo $book_name.'<br>';
echo $img_row['big_img'].'<br>';
}
Thanks for your help and time!
Instead of having a sub-query in a loop (which is nearly ALWAYS a bad idea!), use a JOIN instead, which simplifies it to one query instead of two. Then set a condition that big_img should not be empty. This guarantees that you will only find rows where there's an image matching the book. LIMIT will still only ensure the return of 6 rows. <> in MySQL is the same as !=.
$slider_sql = "SELECT b.book_name, i.big_img
FROM books b
JOIN images i
ON i.book_id=b.id
WHERE i.big_img <> ''
LIMIT 6";
$result = $conn->query($slider_sql);
while ($row = $result->fetch_assoc()) {
echo $row['book_name'].'<br>';
echo $row['big_img'].'<br>';
}
MySQL JOIN

How i can compare the result in one query or two?

I am trying to fetch last 10 topics from smf database but topics are in two separate tables.
Subject, Post Time and Message ID in smf_messages.
Topic ID and Topic First Message in smf_topics.
I wrote this code to fetch topics but i dont know how to compare these two results.
$result = mysql_query("select subject,id_msg,id_topic from smf_messages");
$result2= mysql_query("select id_first_msg from smf_topics");
if(mysql_num_rows($result)!=0)
{
while($read = mysql_fetch_object($result))
{
if ($read->id_msg==$read->id_topic) {
echo "<a href='../index.php?topic=" . $read->id_topic . "'>".$read->subject."</a><br>";
}
}
You probably want the following query
select subject, id_msg, id_topic, id_first_msg
from smf_messages
left join smf_topics on smf_message.id_msg = smf_topics.id_first_msg
bind the records by joining in sql:
select subject id_msg, id_topic, id_first_msg from smf_messages
join smf_topics on smf_messages.id_msg = smf_topics.id_topic
mysql have many many options, with a small google search you could found about left join.
tuttorial and examples.
Fist thing you have to do is stop using mysql_* and start using mysqli_* or pdo learn about sql injections
Your query should look like this.
select smf_messages.subject,smf_messages.id_msg,smf_messages.id_topic from smf_messages left join smf_topics on smf_topics.id_first_msg=smf_messages.id_msg
If you want to do that without using SQL, this is my solution it's not good but you can have an idea of how it works:
$messages = array();
$topics = array();
while($readmessage = mysql_fetch_object($resultmessage)) {
array_push($messages, $readmessage);
}
while($readtopic = mysql_fetch_object($resulttopic)) {
array_push($topics, $readtopic);
}
foreach ($topics as $topic) {
$result = array_search($topic->id_first_message);
if($result != true){
//HERE $result IS THE INDEX OF FIRST MESSAGE IF IT IS IN THE MESSAGES ARRAY
$messages[$result].id_msg //Access message attributes
}
}

Counting the number of times each variable appears in table

Basically, I am seeking to know if there is a better way to accomplish this specific task.
Basically, what happens is I query the db for a list of "project needs" -- These are each uniquer and only appear once.
Then, I search another table to find out how many members have the required "skills - which are directly correlated to the project needs".
I accomplished exactly what I was trying to do by running a second query and then inserting them into an array like this:
function countEachSkill(){
$return = array();
$query = "SELECT DISTINCT SKILL_ID, SKILL_NAME FROM PROJECT_NEEDS";
$result = mysql_query($query) or die(mysql_error());
$num_rows = mysql_num_rows($result);
while($row = mysql_fetch_assoc($result)){
$query = "SELECT COUNT(*) as COUNT FROM MEMBER_SKILLS WHERE SKILL_ID = '".$row['NEED_ID']."'";
$cResult = mysql_query($query);
$cRow = mysql_fetch_assoc($cResult);
$return[$row['SKILL_ID']]['Count'] = $cRow['COUNT'];
$return[$row['SKILL_ID']]['Name'] = $row['SKILL_NAME'];
}
arsort($return);
return $return;
}
But I feel like there has to be a better way (perhaps using some kind of join?) that would return this in a result set to avoid using the array.
Thanks in advance.
PS. I know mysql_ is depreciated. It is not my choice on which to use.
SELECT P.SKILL_ID, P.SKILL_NAME, COUNT(M.SKILL_ID) as COUNT FROM PROJECT_NEEDS P INNER JOIN MEMBER_SKILLS M
ON P.SKILL_ID=M.SKILL_ID
GROUP BY P.SKILL_ID, P.SKILL_NAME
I've adjusted Nriddens answer to accomodate for the select distinct, Im under the belief that his adjustment would be ok given SKILL_ID is a primary key
function countEachSkill(){
$return = array();
$query = "
SELECT
COUNT(*) AS COUNT,
PROJECT_NEEDS.SKILL_NAME,
PROJECT_NEEDS.SKILL_ID
FROM
(SELECT DISTINCT
SKILL_ID, SKILL_NAME
FROM
PROJECT_NEEDS) AS PROJECT_NEEDS
INNER JOIN
MEMBER_SKILLS
ON
MEMBER_SKILLS.SKILL_ID = PROJECT_NEEDS.SKILL_ID
GROUP BY PROJECT_NEEDS.SKILL_ID";
$result = mysql_query($query) or die(mysql_error());
$num_rows = mysql_num_rows($result);
while($row = mysql_fetch_assoc($result)){
$return[$row['SKILL_ID']]['Count'] = $row['COUNT'];
$return[$row['SKILL_ID']]['Name'] = $row['SKILL_NAME'];
}
arsort($return);
return $return;
I am subquerying on the select distinct because I dont believe you have a dedicated skills table with an auto inc primary key, if that was there I wouldn't be using a subquery.
Can you test this query
select project_needs.*,count(members_skills.*) as count from project_needs
inner join members_skills
on members_skills.skill_id=project_needs.skill_id Group by project_needs.skill_name, project_needs.skill_id

How does one go about deleting records from an array with Joins

I have a query with multiple joins in it. After I take the results and run it through a Id-checker I want to be able to delete records from that array where the IDDestination equals $ID.
Since this query has joins on it and I am filtering them based on one of the joined tables, How do I go about deleting those records from the array based off that joined table?
And I only wanted this to happen after the user confirms.
$query = "
select d.IDCourse,
d.name as course_name,
d.slug,
d.short_description,
d.address,
e.city_name,
e.state_code,
d.zip,
e.city_slug,
e.state_slug,
h.IDDestination,
LOWER(e.iso_code) as country_slug, a.*,
b.IDTeetimeType,
c.name as teetime_type,
b.start_time,b.end_time,
(case dayofweek(a.teetime_dt)
when 1 then `b`.`sun`
when 2 then `b`.`mon`
when 3 then `b`.`tue`
when 4 then `b`.`wed`
when 5 then `b`.`thu`
when 6 then `b`.`fri`
when 7 then `b`.`sat`
end) AS `price`, g.tax_rate, f.alias
from cart_course_teetimes a
join course_priceplan b
on a.IDCoursePricePlan = b.IDCoursePricePlan
join course_teetime_type c
on b.IDTeetimeType = c.IDTeetimeType
join course d
on b.IDCourse = d.IDCourse
join vw_cities e
on d.IDCity = e.IDCity
join destinations_cities h
on h.IDCity= d.IDCity
LEFT JOIN (SELECT * FROM media_mapping WHERE is_main_item=1 AND IDGalleryType=3) f
ON d.IDGallery = f.IDGallery
left join course_tax
g on a.IDCourseTax = g.IDCourseTax
where a.IDCart = :cart_id
order by d.name, a.teetime_dt, b.start_time;";
$prepared = array(
"cart_id" => $idCart,
);
$conn = new DBConnection();
$results = $conn->fetch($query, $prepared);
$conn = null;
$results = !empty($results) ? $results : array();
$id = null;
foreach($results as $row) {
// Set ID for the first record.
if($id === null)
$id = $row['IDDestination'];
// will stay true, otherwise it's false and we should kill the loop.
if($id != $row['IDDestination']) {
$newid=$row['IDDestination'];
echo "<script type='text/javascript'> emptycart();</script>";
$query = "DELETE FROM cart_course_teetimes a WHERE h.IDDestination='.$id.'";
$res =mysql_query($query) or die (mysql_error());
break;
}
}
This is incorrect PHP:
$query = "DELETE FROM cart_course_teetimes a WHERE h.IDDestination='.$id.'"
You're already inside a "-quoted string, so . PHP concatenation operators aren't operators, they're just a period.
You want either of these instead:
$query = "DELETE FROM cart_course_teetimes a WHERE h.IDDestination='" . $id . "'";
$query = "DELETE FROM cart_course_teetimes a WHERE h.IDDestination='$id'"
Right now you're producing
... WHERE h.IDDestination = .42.
which is not valid SQL.
Plus it appears you're mixing database libraries. You've got $conn->fetch() which implies you're using one of the OO db libraries (mysqli? pdo? custom wrapper?). But you then call mysql_query(). Unless you've EXPLICITLY called mysql_connect(), that delete query will never execute. Database connections made in one of the libraries are utterly useless in any of the other libraries.

How to SELECT an articles and its comments from mysql?

I read an article and its comments from mysql database with two separate queries as
$result = mysql_query("SELECT * FROM articles WHERE article_id='$id'");
$row = mysql_fetch_array($result);
$title=$row['title'];
........
AND
$result = mysql_query("SELECT * FROM comments WHERE article_id='$id'");
while($row = mysql_fetch_array($result)) {
$comment_title=$row['title'];
.........
}
Is the best way to read this set of data from database? OR
Is it possible to catch the data through one query or one transaction?
NOTE: My issue is that first query for article is only for one row; but the second one needs a loop to process (and display in html) several comments.
$result = mysql_query("SELECT articles.title as article_title, comments.title as comment_title FROM articles LEFT JOIN comments ON articles.article_id = comments.article_id WHERE articles.article_id = '$id'");
$row = mysql_fetch_array($result);
$article_title=$row['article_title'];
$comment_title=$row['comment_title '];
You can do it in this way -
SELECT a.*, c.* FROM articles a
LEFT JOIN comments c
ON a.article_id = c.article_id
WHERE a.article_id='$id';
Is the best way to read this set of data from database?
Sure, it is.
Is it possible to catch the data through one query
Yes, it's possible but there is no point in doing that.
Why do you ask?

Categories