Mysql - Subqueries w/ Counting Items - php

I have 2 tables .. categories & deals. Ultimately, I want to do the following:
// foreach category
// Display category title
// show 3 entries in deals where it matches category title above, along with a link saying: "View (count) More Deals
Now, there are a couple of ways for me to do this:
// The "bad" way:
// foreach category
// fetch count of total deals in this category
// Display category title (once)
// Fetch & Display 3 deals
// Display "View (count) more deals
// This is just quite a few queries for one page
The "other" way:
SELECT count(deals.id),
category.name as category_name,
deal.name as deal_name
FROM $db[ddd_deals] as deals
JOIN $db[ddd_categories]
ON $db[ddd_categories].id = $db[ddd_deals].category_id
WHERE deals.city_id = '$_SESSION[city_id]'
ORDER BY $db[ddd_categories].name
The above does everything except display the number of deals in each category, and only display 3 deals per category
-Should I be selecting FROM the deals table (or from the categories table, then grab the deals?)
// I also tried the following. It returns what category and deal, but the count is off (it is only displaying 1):
SELECT count(deals.id) as cc,
cat.name as cat_name,
deals.name as name
FROM ddd_categories as cat
JOIN ddd_deals as deals
ON deals.category_id=cat.id
GROUP BY deals.id
ORDER BY cat.id

Just a quick one, whether you group by deals.id or .., the order by came at an incorrect place.
select cc, cat_name, name from (
SELECT count(deals.id) as cc, cat.name as cat_name, deals.name as name
FROM ddd_categories as cat
JOIN ddd_deals as deals on deals.category_id=cat.id
GROUP BY deals.id
)
ORDER BY xxx;

You need to GROUP BY cat.id instead of deals.id. Try to following:
SELECT count(deals.id) as cc, cat.name as cat_name, deals.name as name
FROM ddd_categories as cat JOIN ddd_deals as deals ON deals.category_id=cat.id
GROUP BY cat.id

Related

Can I do this with 1 query?

I am creating a simple blog with categories in php.
I want that myblog.com/category.php?id=3 show me this:
TITLE of the category 3
// other stuff
ALL POSTS of the category 3
So, actually I do 2 queries ( 1 for getting the title and 1 for getting the posts ).
Is there a way to do this with 1 query ?
Depending on your database tables, you could something like that
SELECT c.title, p.data FROM category c LEFT JOIN post p ON p.category = c.category ORDER BY p.date
The category title will be repeated for every post though
If you need all fields from these tables so I think you should use #Damien's way.
If you need only titles you can use following query. In this query the first row is a title of a CATEGORY and next rows are titles of posts.
select * from
(
select 0 as ordField, categoris.Category_TITLE as Title from categoris where id =3
union all
select 1 as ordField, POSTS.Post_TITLE as Title from POSTS where category_id=3
) t order by ordField

Group by ID and Show all results from mysql

I have 2 tables
tabcats - Cat_Id, Cat_Name
tabnews - News_Id, News_Name, Cat_Id
So I'm trying to make a select on database and return all results but using
Group by Cat_Id
so my results was supposed to be
let's say I have 3 Categories and 5 News
Results
Cat_Name 1
News_Name (1)
News_Name (2)
Cat_Name 2
News_Name (3)
News_Name (4)
Cat_Name 3
News_Name (5)
I read something about using LEFT OUTER JOIN but I don't get this clearly.
First you need to be clear about yourself. What I supposed that you tried to do is select some counts of latest news,isn't it? Try query similar to this one: The below query Find the course ID, semester, year and title of each course offered by the Comp. Sci. department
select section.course_id, semester, year, title from section, course where section.course_id = course.course_id and dept_name = ‘Comp. Sci.'
Ordering can be done as follows:
return(mysql_query("SELECT * FROM tabNews GROUP BY news_id DESC LIMIT *counts*"));
This is to list all news together with cat name sorting by cat name follow by news name.
SELECT News_Name,Cat_name from tabNews n left join tabCat c on n.cat_id=c.cat_id
ORDER BY c.cat_name,n.news_name

Sorted output of a joined MySQL result in PHP

Doing an allnighter on a project and my mind is blank atm... Simple question really:
I have two MySQL tables, product and category. Each product belongs to exactly one category. Every category has several products.
SELECT
p.uid as product_uid, p.name_NL as product_name, p.price as product_price,
c.uid as category_uid, c.name_NL as category_name
FROM
product p, category c
WHERE
p.category_uid = c.uid
This gives me a nice overview of all products in their respective category. My question is about outputting this data on the page. I'm aiming for this:
<h1>Category name</h1>
<p>Product in this category</p>
<p>Other product in this category</p>
<h1>Next category</h1>
<p>Product in next category</p>
My mind is completely blank right now. How would one go about doing this?
I would like to avoid doing subqueries (if possible).
Kind regards,
M
What about adding ORDER BY category_uid so that the products are ordered by category in your SQL query. Then using PHP, loop through each product (row) and when you encounter a new category, add a new header.
Example:
<?php
// ...
$previous_category_uid = null;
// Loop through each row.
while ( $row = $result->fetch_assoc() )
{
// If the category UID is not the same as the one from the previous row, add a header.
if ( $previous_category_uid != $row['category_uid'] )
{
echo '<h1>' . $row['category_name'] . '</h1>';
$previous_category_uid = $row['category_uid'];
}
}
The benefit of this method is that you don't have to nest queries. A single query will suffice.
Don't you just need to use a GROUP BY category_uid ?
Generally speaking you have two options:
Get all the data at once (like you are doing currently) then use PHP to either pre-sort the data by category. Then do your output looping over this array. So 1 query, 2 + n loops (where n is the number of categories).
Get all your categories and then loop over those for output. In each iteration you will need to query all products for that loop. So 1 + n queries, 1 + n loops (where, again, n is the number of categories).
Option 2 might be more straightforward, but clearly there are more queries. In the end, it's your call.
Assuming you're looking for alphabetical ordering for category names and products within each category:
SELECT
p.uid as product_uid, p.name_NL as product_name, p.price as product_price,
c.uid as category_uid, c.name_NL as category_name
FROM product p INNER JOIN category c ON p.category_uid = c.uid
ORDER BY category_name, product_name
This also converts your query's Cartesian product and WHERE to an inner join.
To output with the headers you want, just loop over the returned rows, and keep track of the category you're in. Whenever the category of the current row is different from the previous one, you print a new h1 for the new category and update the stored "current" category.

MySQL associated table COUNT() and GROUP BY

I am doing a pretty normal routine, but having a tough time getting my output correct.
I have two tables: *ads_list* (listings) and *ads_cate* (categories).
I am currently displaying my category list like so:
SELECT id, cateName FROM ads_cate ORDER BY cateName
What I am trying to achieve: count of all items in each category in this format:
Category | Number of Ads
categoryName 56
This is my current code, and have been tweaking but getting no output in my array:
SELECT
ads_cate.id,
ads_cate.cateName, // Category Name
ads_list.id,
ads_list.COUNT(title), // Title of ad
ads_list.Category // Relational Category ID INT(11)
FROM
ads_cate,
ads_list
GROUP BY cateName
ORDER BY cateName
I am calling in all required fields and running a COUNT() on my title field (as these are unique for each ad) and then I am grouping by cateName which also seems correct.
See what this gives you. I think it is what you need.
SELECT
ads_cate.cateName, // Category Name
COUNT(ads_list.id), // Title of ad
FROM
ads_cate
INNER JOIN
ads_list
ON ads_cate.id = ads_list.category
GROUP BY cateName
ORDER BY cateName

SQL/PHP: Order by highest vote from different table

I needed to recommend to the visitor similar items to the one they where looking at. So I asked in another question for a SQL query to get items with the same categories (from a 'categories' table). The next is the correct code I'm actually using:
SELECT c2.itemID
FROM categories c1
JOIN categories c2 ON c1.catID = c2.catID
WHERE c1.itemID = :id
AND c2.itemID <> :id
GROUP BY c2.itemID
ORDER BY count(c2.itemID) DESC;
It returns items ordered by the number of categories matches (from a table containing 'itemIDs' and 'catIDs'). So for example: item 1 have categories 2,3,4,5,6 and item 2 have categories 2,3,4,5,6 and item 3 have categories 3,5,6 then if I compare item 1 (the one the visitor is looking at) to item 2 and 3 I need to get item 2 first and then item 3 because item 2 have more categories matches than item 3.
NOW: I need also to to order the results by highest vote. The items votes are in a different table. The table 'votes' contain two columns: 'itemID' and 'total_value', 'total_value' being the final rate.
So, How to order the results also by the number of categories matches and also by highest vote from a different table???
Update: The number if items in the table is 8000+. I think the better thing to do to recommend the most similar items is to order it first by items with the exact set of categories and then by votes. Any ideas? Thanks!
SELECT c2.itemID
FROM categories c1
JOIN categories c2 ON c1.catID = c2.catID
JOIN votes v ON v.itemID=c1.itemId
WHERE c1.itemID = :id
AND c2.itemID <> :id
GROUP BY c2.itemID
ORDER BY count(c2.itemID), v.total_value DESC;

Categories