Mysql Query Join Table on the most recent row - php

I have a page of categories, they worked fine until I did a join.
The categories display like so:
category 1-----------------------0----------0
discussion 1 by someone
category 2-----------------------0----------0
discussion 2 by someoneelse
Now where it says discussion, I need to display the last discussion posted to that category based on it's discussion_id. I have tried ORDER BY ... DESC but it sorts by category names not the discussion names and posted by.
$sql = "SELECT *, COUNT(d.cat_id) as count
FROM discussions as d
LEFT JOIN categories c ON (c.cat_id = d.cat_id)
RIGHT JOIN soldiers s ON (s.uid = d.discussion_poster)
GROUP BY d.cat_id";
$result = query($sql);
while (($row = mysqli_fetch_assoc($result)) != false) {
$cat_id = $row['cat_id'];
$discussion_id = $row['discussion_id'];
$cat_title = $row['cat_title'];
$discussion_title = $row['discussion_title'];
$discussion_time = $row['discussion_time'];
$count = $row['count'];
$discussion_poster_id = $row['discussion_poster'];
$discussion_poster = $row['soldier'];
}

$sql = "
SELECT *
FROM categories c
INNER JOIN
(
SELECT MAX(discussion_id) discussion_id,
COUNT(discussion_id) as count,
cat_id
FROM
discussions
GROUP BY
cat_id
) as d1
ON (c.cat_id = d1.cat_id)
INNER JOIN discussions as d
ON (d1.discussion_id = d.discussion_id)
INNER JOIN soldiers s
ON (s.uid = d.discussion_poster)
GROUP BY d.cat_id";

Related

MySQL count from intermediary table

I'm trying to find the most used categories in an intermediary table which contains two ids, I'm running this to find all the counts of posts against categories.
$data = $conn->query('SELECT * FROM category WHERE category_name ORDER BY category_name');
foreach($data as $row) {
$sql = "SELECT COUNT(p_id) FROM p_categories c,category ca WHERE c.category_id = ca.category_id AND category_name = :category_name";
$q = $conn->prepare($sql);
$q->execute(array(':category_name' => $row['category_name']));
$catco = $q->fetch();
echo '<p>'.$row['category_name'].' ('.$catco[0].')</p>';
}
This returns all the categories, but I want to limit it to only the top four categories having most p_id. I tried limiting the count query to 4 but that didn't work.
Here are the tables:
posts: p_id, p_name
p_categories: p_id, category_id
category: category_id, category_name
You can do this in a single query
$sql = "SELECT p_categories.category_id, COUNT(*) AS cnt, category.category_name
FROM p_categories
LEFT JOIN category
ON p_categories.category_id = category.id
GROUP BY `category_id`
ORDER BY cnt
DESC LIMIT 4"
$data = $conn->query($sql);
foreach($data as $row) {
echo '<p>'.$row['category_name'].' ('.$row['cnt'] .')</p>';
}

Getting Multiple Values from a table column into a repeating row

I'm using Wordpress and I have to figure out how to get multiple values out of the same column and turn them into variables.
The last step is I just want the data to display in a table like so:
Bob Company1 <br>
Alex Company2
Instead I get either Bob Alex Company1 Company 2 or
Bob <br>
Alex<br>
Company1<br>
Company2
Here's two different versions I'm working with:
$sql = "SELECT meta_value as guest from wp_postmeta INNER JOIN wp_posts ON wp_posts.ID = wp_postmeta.post_id WHERE post_type='guests' AND meta_key='guest_name' UNION SELECT meta_value as company from wp_postmeta INNER JOIN wp_posts ON wp_posts.ID = wp_postmeta.post_id WHERE post_type='guests' AND meta_key='guests_company'";
$result = mysql_query($sql);
$NumberOfResults=mysql_num_rows($result);
if (mysql_num_rows($result) == 0) {
echo "No Guests yet... stay tuned!";
exit;
}
while(list($guest,$company)= mysql_fetch_row($result))
{
echo "<table><tr><td>".$guest."</td><td>".$company."</td></tr></table>";
}
or
$sql = mysql_query("SELECT meta_value as guest from wp_postmeta INNER JOIN wp_posts ON wp_posts.ID = wp_postmeta.post_id WHERE post_type='guests' AND meta_key='guest_name' LIMIT 2 UNION SELECT meta_value as company from wp_postmeta INNER JOIN wp_posts ON wp_posts.ID = wp_postmeta.post_id WHERE post_type='guests' AND meta_key='guests_company'");
$i = 1;
while ($get = mysql_fetch_array($sql))
{
echo '<table><tr><td>'.$get["guest"].'</td><td>'.$get["company"].'</td></tr></table>';
$i++;
}
ANY HELP would be so appreciated!!! thanks!
Edit: In case anybody in the future wants to create their own widget using advanced custom fields in Wordpress, here's the final product more or less:
$sql = "SELECT p.ID AS post_id, g.meta_value as guest, c.meta_value as company, d.meta_value as date
FROM wp_posts p
JOIN wp_postmeta g ON g.post_id = p.id AND g.meta_key = 'guest_name'
JOIN wp_postmeta c ON c.post_id = p.id AND c.meta_key = 'guests_company'
JOIN wp_postmeta d ON d.post_id = p.id AND d.meta_key = 'show_date'
WHERE p.post_status = 'publish'
ORDER by d.meta_value DESC";
$query = mysql_query($sql);
echo '<table><tr><th>Guest</th><th>Company</th><th>Show Date</th></tr>';
while ($get = mysql_fetch_array($query)) {$newDate = date("m-d-Y", strtotime($get["date"]));
echo '<tr><td>'.$get["guest"].'</td><td>'.$get["company"].'</td><td>'.$newDate.'</td></tr>';
}
echo '</table>';
Really appreciated doublesharp's help on this.
If I understand your question correctly, you have to write the code to display table like this:
echo '<table>';
while ($get = mysql_fetch_array($sql))
{
echo '<tr><td>'.$get["guest"].'</td><td>'.$get["company"].'</td></tr>';
}
echo '</table>';
If the postmeta values are attached to different posts as indicated by the different 'post_type' values in your query, then you will need some other identifying information to link them together. If there is a single post_id that has both a guest_name and guest_company meta_value then you can join it twice to get the results. Using a UNION will always result in them coming back in different rows.
// Join the postmeta table to posts twice, once for each meta_key.
$sql = <<<SQL
SELECT p.ID AS post_id, g.meta_value as guest, c.meta_value as company
FROM wp_posts p
JOIN wp_postmeta g ON g.post_id = p.id AND g.meta_key = 'guest_name'
JOIN wp_postmeta c ON c.post_id = p.id AND c.meta_key = 'guests_company'
WHERE p.post_status = 'publish'
SQL;
// Execute the query
$query = mysql_query($sql);
// Start your table for output
echo '<table>';
while ($get = mysql_fetch_array($query)) {
// Write the output of each row
echo '<tr><td>'.$get["guest"].'</td><td>'.$get["company"].'</td></tr>';
}
// Close the table
echo '</table>';
If this is inside Wordpress, I would recommend using the $wpdb object for your query.

Combining 2 queries into 1

I'm looking to optimize two queries into one, if possible.
My first query searches for all the authors of a lyrics... Then, for each author found, i want to find the total numbers of lyrics the author was involded in...
Right now, im executing the first query and for each row found, i'm launching another query to get the authors total lyrics he was involved... So, if there is 4 authors i will end up launching 4 more queries...
That is to many queries in my opinion. That is why i've decided to write here, so i can get help on how to optimize my query...
This is the query i'm executing to get the author(s) responsable for a lyrics:
$sql = "SELECT author.author_id, author.name
FROM track INNER JOIN lyrics_author ON track.lyrics_id = lyrics_author.lyrics_id
INNER JOIN author ON lyrics_author.author_id = author.author_id
WHERE track.track_id = $trackid ";
This is the query to get the total number of lyrics the author as writing:
$total = "SELECT lyrics_author.author_id, count(*) as total
FROM lyrics_author
WHERE lyrics_author.author_id = $author_id
GROUP BY lyrics_author.author_id";
This is a sample of the code:
<?php
$trackid = 5;
$sql = "SELECT author.author_id, author.name
FROM track INNER JOIN lyrics_author ON track.lyrics_id = lyrics_author.lyrics_id
INNER JOIN author ON lyrics_author.author_id = author.author_id
WHERE track.track_id = $trackid ";
$result_author = # $conn->query($sql);
while ($row_author = $result_author->fetch_assoc()) {
$author_id = $row_author['author_id'];
$total = "SELECT lyrics_author.author_id, count(*) as total
FROM lyrics_author
WHERE lyrics_author.author_id = $author_id
GROUP BY lyrics_author.author_id";
$result_total_lyrics = # $conn->query($total);
$t = $result_total_lyrics->fetch_assoc();
echo $t['total'];
$result_total_lyrics->free();
}
$result_author->free();
?>
Is it posible to optimize this query? If yes, how? Is there a link you could refer, so i can learn...
Thanks
Marco
SELECT
author.author_id,
author.name,
COUNT(DISTINCT more_tracks.lyrics_id) AS total
FROM track
INNER JOIN lyrics_author USING (lyrics_id)
INNER JOIN author USING (author_id)
LEFT JOIN lyrics_author AS more_tracks USING (author_id)
WHERE track.track_id = $trackid
GROUP BY author.author_id
That's confusing as heck. Why are you passing in a trackid as a lyricsid when you have a property called lyricsid??
Anyway
Select author.author_id, author.name, Count(*)
inner join
(SELECT lyrics_author.author_id
FROM lyrics_author
INNER JOIN tracks ON track.lyrics_id = lyrics_author.lyrics_id
WHERE track.track_id = $lyricsid";
) as lyricalauthors
inner join lyrics_author on lyrics_author.author_id = lyricalauthors.author_id
On author.author_id = lyricalauthors.author_id
Group By Author.author_id,author.name
I think ...

echo list of products by category

Can someone tell me how to echo data that is relating with another table?
I have a table
tbl_category_products:<
- id_categorys
- category
And other table for the products
tbl_products:
- title
- description
- id_categorys
How could I echo the list of products by category in PHP?
Here is some code, but no sucess.
Im trying but no sucess, here is the original code
Table names:
tbl_categorias_noticias
- id_categoria_noticia
- categoria
tbl_noticias
- id_noticia
- id_categoria_noticia
-titulo
-decricao
-msg
-nome_arquivo
-legenda
<?php
$categoryId = 1;
$sql_visualizar = mysql_query("SELECT * FROM tbl_noticias AS t1 JOIN tbl_categorias_noticias c
ON c.id_categoria_noticia=t1.id_categoria_noticia WHERE id_categoria_noticia = {$categoryId}");
while($linha = mysql_fetch_array($sql_visualizar)){
$titulo = $linha ['titulo'];
$descricao = $linha['descricao'];
$msg = $linha['msg'];
$legenda = $linha['legenda'];
$nome_arquivo = $linha['nome_arquivo'];
$id_noticia = $linha['id_noticia'];
?>
You need a join:
SELECT t1.title, t1.description, t2.category
FORM tbl_products t1
LEFT JOIN tbl_category_products t2 ON t1.id_categorys = t2.id_categorys
Something like this
First of all: mysql connect
$categoryId = 1;
$query = "SELECT t1.* FROM tbl_products AS t1 JOIN tbl_category_products c
ON c.id_categorys=t1.id_categorys WHERE id_categorys = {$categoryId}";
$result = mysql_query($query);
while($r = mysql_fetch_assoc($result)) {
//show your products
}
Use a JOIN to query both tables
SELECT p.title, p.decription, c.category
FROM tbl_products p
JOIN tbl_category_products c
ON c.id_categorys=p.id_categorys
ORDER BY c.category ASC
SELECT tp.title, tp.description, tcp.category FORM tbl_products tp,tbl_category_products tcp where tp.id_categorys = tcp.id_categorys
Try this
SELECT t1.title, t1.description, t2.category
FORM tbl_products t1
JOIN
tbl_category_products t2
ON t1.id_categorys = t2.id_categorys
WHERE t1.id_categorys = 'myCategory'

How to select three rows from each different category from a table?

I have two tables category and hotels where category.id should be equal to hotels.catid. Now how do I select 3 rows from each different category from the hotels table.
I have this query:
select h.* from hotels h inner join category c on h.catid = c.id
order by h.catid, h.hid
This selects all records, but I want to select three rows per different category so in all it should return 9 rows with 3 rows for each category.
If this can not be done in MySQL, can it be done in PHP?
Try this:
select h.*
from category c
inner join (select * from hotels h where c.id = h.catid limit 3) h
order by h.catid, h.hid
I'm wondering if that is valid syntax in MySQL...
If not, you could try:
select h.*
from category c
inner join hotels h on (c.id = h.catid)
where h.hid in (select h2.hid from hotels h2 where h2.catid = c.id limit 3)
3rd attempt:
select h.*
from category c
inner join hotels h on (c.id = h.catid)
where exists (select * from (select h2.hid from hotels h2 where h2.catid = c.id limit 3) h3 where h3.hid = h.hid)
Alright here's another attempt which is just plain ugly:
select * from hotels h
where h.hid <=
(select min(h1.hid)
from hotels h1
where h1.catid = h.catid
and h1.hid > (select min(h2.hid)
from hotels h2
where h2.catid = h1.catid
and h2.hid > (select min(h3.hid)
from hotels h3
where h3.catid = h2.catid)
)
)
I hope it works. If it doesn't though, hopefully it will give you ideas of something that might work, or maybe even give others ideas of how to solve this problem. At the very least it could be used to see what doesn't work.
You could do it in the following way.
select
h.*
from
hotels h
where
h.catid IN (
select
c.catid
from
category c
order by
RAND()
limit 1
)
order by
h.catid, h.hid
limit 3
This should give you 3 hotels in one random category.
With php you could do it like this
$i = 0;
$sql = "select catid from category order by rand()";
$query = mysql_query($sql);
while($row = mysql_fetch_object($query))
{
if($i < 3)
{
$i++;
$categories[] = $row->catid;
}
else
{
break;
}
}
foreach($categories as $catid)
{
$i = 0;
$sql = "select * from hotels where catid = $catid";
$query = mysql_query($sql);
while($row = mysql_fetch_object($query))
{
if($i < 3)
{
$i++;
$hotels[] = $row;
}
else
{
break;
}
}
}
You should be able to use DISTINCT(category) and limit query to 3 results
So you want to find three hotels per category... there are options!
The easiest method I can think of is to perform the query per category.
SELECT
h.*
FROM
hotels h
WHERE
h.catid = 1
LIMIT 0, 3
hi i am not sure about the query but i have a alternate way.first find all the category array and the find the 3 record from the hotels tables.
step I:
$sql="SELECT * FROM Table category ";
execute the query and place results in category array
Step II:
Make a loop
For($i=0;isset(category array [$i]);$i++)
{
query for 3 record from hotel tabel
Execute this and store all data in array
}
In this way you can also get the record.This is not the exact solution of your problem but you can use this for resolving your problem

Categories