Counting the most amount of items assigned to a user using greatest - php

I am trying to query 5 separate tables in my mysql database, and display the actor with the most amount of items assigned to them. The table structures are as follows;
item
itemid | item | description | brand | date | time | path |
actor
actorid | name | actorthumb | bio |
brand
brandid | brandname | description | image |
movie
movieid | title | genre | year | moviethumb | synopsis|
request
requestid | userid | itemid | brandid | movieid | actorid | content | requestdate |
I presume I need to join the request, actor and items table together, using COUNT function count how many items are assigned to an actor, then use GREATEST to display the actor with the highest amount of items assigned to them?
The query to join all the tables is
$query = "SELECT greatest i.*, a.*, b.*, m.*, r.* FROM item AS i, actor AS a, brand AS b, movie AS m, request AS r
WHERE r.itemid = i.itemid
AND r.actorid = a.actorid
AND r.brandid = b.brandid
AND r.movieid = m.movieid";
Please confirm the best way to do the above?

SELECT a.actorid, a.name
FROM request r
INNER JOIN actor a
ON r.actorid = a.actorid
GROUP BY a.actorid, a.name
ORDER BY COUNT(DISTINCT r.itemid) DESC
LIMIT 5

The query to join all the tables is
$query = "SELECT i.*, a.*, b.*, m.*, r.* FROM item AS i, actor AS a, brand AS b, movie AS m, request AS r
WHERE r.itemid = i.itemid
AND r.actorid = a.actorid
AND r.brandid = b.brandid
AND r.movieid = m.movieid
ORDER BY count(i.*) DESC";

Related

count total volume by category

I have 3 tables
Company_categories
companies
daily_rates
I want to count total volume industry wise of all the company exist within the category of companies
for example category A contains 3 companies and category B contains 5 companies so I want to sum total volume of all 3 companies in category A and so on for all categories I tried to do so but I am confused how to do with 3rd table as of I am easily been able to count the companies contains in category but not sure how to count the volume of all companies exist in a category
my table structure
company_categories
id name
+------------+----------+
| 1 | A |
|------------|----------|
| 2 | B |
|------------|----------|
companies
id name category
+------------+----------+-----------+
| 1 | co 1 | 1 |
|------------|----------|-----------|
| 2 | co 2 | 2 |
|------------|----------|-----------|
| 3 | co 3 | 1 |
|------------|----------|-----------|
daily_stock_rates
id traded_volume company_id
+------------+------------------+---------------+
| 1 | 40 | 1 |
|------------|------------------|---------------|
| 2 | 80 | 2 |
|------------|------------------|---------------|
| 3 | 30 | 3 |
|------------|------------------|---------------|
here is my code
$sql = mysqli_query($connect, "SELECT c.id category_id, c.name category_name, com.id, com.category count( dsr.total_traded_volume ) total_volume
FROM company_categories c
INNER JOIN companies com ON c.id = com.category
LEFT JOIN daily_stock_rates dsr ON com.id = dsr.company_id
GROUP BY com.category
ORDER BY total_volume DESC LIMIT 10");
while($data = mysqli_fetch_assoc($sql)) {
echo $data['category_name'] . ": .".$data['total_volume'];
echo "<br />";
}
Can Anyone help me out
joint twice to get all the rates related to the category
SELECT cat.name, SUM(rat.traded_volume) volume
FROM company_categories cat
JOIN companies comp ON comp.category = cat.id
JOIN daily_stock_rates rat ON rat.company_id = comp.id
GROUP BY cat.name
ORDER BY volume DESC
LIMIT 10
Most important diff to your query:
you need SUM(), not COUNT()
select only what you asked: volume by category. You cannot select
names of companies alongside (what company you would want to see
there anyway)
I don't think it's the join you got wrong, it's the select list and the group by clause.
First of all, if you want the total of the volume, then use sum(), not count(). Also, do not include so many fields in the select list if you want the total by category:
SELECT c.id category_id, c.name category_name, sum( dsr.total_traded_volume ) total_volume
FROM company_categories c
LEFT JOIN companies com ON c.id = com.category
LEFT JOIN daily_stock_rates dsr ON com.id = dsr.company_id
GROUP BY c.id
ORDER BY total_volume DESC LIMIT 10

MySQL Join three tables and display 0 if null

I have three tables:
person_table
id| name | gender
1 | Joe | male
2 | Jane |female
3 | Janet | female
4| Jay | male
etc...
product_table
id| name
1 | magazine
2 | book
3 |paper
4 | novel
etc...
**person_product
person_id| product_id | quantity
1 | 1 | 1
1 | 3 | 3
2 | 3 | 1
4 | 4 | 2
etc...
I have tried to make a query that will return a table like this:
person_id| person_name | product_name| quantity
but i can't make it so that if lets say John has no books, it should display
(johns id) John|book|0
instead of just skipping this line.
Where did i go wrong?
here is what i managed to come up with:
SELECT p.*, f.name, l.quantity
FROM person_product AS l
INNER JOIN people_table AS p ON l.person_id=p.id
INNER JOIN product_table AS f ON l.product_id=f.id
ORDER BY id`
It seems that you're generating a report of all people, against all products with the relevant quantity; on a large data set this could take a while as you're not specifically joining product to person for anything other than quantity:
SELECT
p.id,
p.name,
p.gender,
f.name,
IFNULL(l.quantity,0) AS quantity
FROM person_table AS p
JOIN product_table AS f
LEFT JOIN person_product AS l
ON l.person_id = p.id
AND l.product_id = f.id
ORDER BY p.id, f.name
Which results in:
Is that more-or-less what you're after?
you need to start with people_table than using left join you need to bring other table data.
as you need 0 value if null than you can use function IFNULL
SELECT p.*, f.name, IFNULL(l.quantity,0)
FROM people_table AS p
LEFT JOIN person_product AS l ON l.person_id=p.id
LEFT JOIN product_table AS f ON l.product_id=f.id
ORDER BY p.id
if has no book shouldn't appear in the table , try this (easy to understand) :
SELECT NAME
,'0'
,'0'
FROM person_table
WHERE id NOT IN (
SELECT person_id
FROM person_product
)
UNION
SELECT person_id
,product_id
,quantity
FROM person_product;

How to get a list of similar items

I have 4 tables:
items
+----+------+---------+-----+
| id | name | city_id | ... |
+----+------+---------+-----+
attributes
+----+------+-----+
| id | name | ... |
+----+------+-----+
item_attribute
+----+---------+--------------+
| id | item_id | attribute_id |
+----+---------+--------------+
city
+----+------+-----+
| id | name | ... |
+----+------+-----+
Items and attributes have relations many-to-many.
Item is located only in one city one-to-many
Question:
I'm using php (Laravel). How can I get Items list (with LIMIT) for one Item with similar attributes in one city? Attribute list is never equals for 2 items.
Is it possible to do with MySQL query?
Example:
| ItemName | Attributes | City |
+----------+-----------------------+------+
| Alpha | one, two, three, four | NY |
| Beta | five, six, seven | NY |
| Gamma | one, three, seven | NY |
| Delta | one, six, eight | CA |
| Epsilon | two, three, four | NY |
| Zeta | ten, nine | NY |
I want to choose similar items for Alpha, they will be: Gamma, Epsilon because they have similar attributes.
Delta won't be chosen, because it's located in another city.
If you have both the item_id and the city_id to pass in:
SELECT i.name,
GROUP_CONCAT(a.name) attributes,
c.name
FROM items i
JOIN city c
ON c.id = i.city_id
JOIN item_attribute ia
ON ia.item_id = i.id
AND EXISTS (
SELECT 1
FROM item_attribute ia1
JOIN item_attribute ia2
ON ia2.attribute_id = ia1.attribute_id
AND ia2.item_id = ia.item_id
WHERE ia1.item_id = :item_id /* Pass in item id variable */
)
JOIN attributes a
ON a.id = ia.attribute_id
WHERE i.city_id = :city_id /* Pass in city id variable */
GROUP BY i.name, c.name
If you just want to pass the example item id: (A little bit sloppy, but should work)
SELECT i.name,
GROUP_CONCAT(a.name) attributes,
c.name
FROM items base
JOIN items i
ON i.city_id = base.city_id
JOIN city c
ON c.id = i.city_id
JOIN item_attribute ia
ON ia.item_id = i.id
AND EXISTS (
SELECT 1
FROM item_attribute ia1
JOIN item_attribute ia2
ON ia2.attribute_id = ia1.attribute_id
AND ia2.item_id = ia.item_id
WHERE ia1.item_id = base.id
)
JOIN attributes a
ON a.id = ia.attribute_id
WHERE base.id = :item_id /* Pass in item id variable */
GROUP BY i.name, c.name
** UPDATE **
Ordering:
...
JOIN (
SELECT ia2.item_id, COUNT(*) count
FROM item_attribute ia1
JOIN item_attribute ia2
ON ia2.attribute_id = ia1.attribute_id
AND ia2.item_id = ia1.item_id
/* AND ia2.id != ia1.id /* If you don't want the original item */
WHERE ia1.item_id = base.id
GROUP BY ia2.item_id
) similar
ON similar.id = ia.item_id
...
ORDER BY similar.count DESC
You can perform INNER JOINS in all
SELECT I.name,I_A.name,city.name FROM attributes as A
INNER JOIN item_attribute as I_A ON I_A.attribute_id = A.id
INNER JOIN city ON I_A.id = city.id
INNER JOIN items as I ON I.id = I_A.item_id
WHERE <Your condition>
To get comma separated values you can refer here
Let me know if I am not getting your point.

Joining Query with Multiple Tables Based on Values

Supposed I have a table posts like below:
| id | type | ref_id |
-----------+--------------+ ---------------
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 3 | 3 |
| 4 | 1 | 4 |
| 5 | 2 | 5 |
| 6 | 3 | 6 |
The type field is to join with other tables, so for example 1=blogs, 2=reviews, 3=photos, and each of them have respective fields, while ref_id is the ID of the blog/review/photo.
What i want to do is to show all latest posts (order by id DESC), while joining with all other tables based on the value of the type, but I want to do it with one query if possible. My no-good query is below:
SELECT * FROM posts
LEFT JOIN blogs ON posts.ref_id = blogs.ID AND posts.type = 1
LEFT JOIN reviews ON posts.ref_id = reviews.ID AND posts.type = 2
LEFT JOIN photos ON posts.ref_id = photos.ID AND posts.type = 3
ORDER BY posts.id DESC
The query doesn't result in anything. Another alternative is to loop the SELECT * FROM posts query and do another query based on the type, but if possible, I'd like to do it in 1 go.
Thanks for the help.
To see why your query does not return anything, consider moving the " AND posts.type = " from JOIN to WHERE clause. It will be:
select * from posts ... where type=1 and type=2 and type=3
Obviously, it will return no results. I know it is not the answer to your question, but I would consider a small change in your table definitions:
(table name: fields)
posts: id
blogs: id, post_id
reviews: id, post_id
photos: id, post_id
In this case you will be able to construct simpler and more traditional queries:
select * from posts
left join blogs on blogs.post_id = posts.id
left join reviews on reviews.post_id = posts.id
left join photos on photos.post_id = posts.id
I guess you want something like this:
( SELECT posts.*, blogs.*
FROM posts
JOIN blogs
ON posts.ref_id = blogs.ID
AND posts.type = 1
UNION ALL
SELECT posts.*, reviews.*
FROM posts
JOIN reviews
ON posts.ref_id = reviews.ID
AND posts.type = 2
UNION ALL
SELECT posts.*, photos.*
FROM posts
JOIN photos
ON posts.ref_id = photos.ID
AND posts.type = 3
)
ORDER BY posts.id DESC

Querying 6 tables unable to echo info from master table

I am trying to query 6 separate tables in my mysql database, the structures are as follows;
item
itemitemid | item | description | brand | date | time | path |
actor
actoractorid | name | actorthumb | bio |
brand
brandbrandid | brandname | description | image |
movie
moviemovieid | title | genre | year | moviethumb | synopsis|
users
userid | name | surname | email | password |
request
requestid | userid | itemid | brandid | movieid | actorid | content | requestdate |
Using the following query I can display for example where the requestid=1 I can see the movie in the request, the actor in the movie, the item of clothing they were wearing and its brand.
$requestid = mysql_real_escape_string($_GET['requestid']);
$query = "select r.requestid, m.*, a.*, i.*, b.*
FROM request r INNER JOIN movie m ON m.movieid = r.movieid
INNER JOIN actor a ON a.actorid = r.actorid
INNER JOIN item i ON i.itemid = r.itemid
INNER JOIN brand b ON b.brandid = r.brandid
WHERE r.requestid = $requestid";
However when I try to echo out "content" and "request date" from the request table. The data simply doesn't appear. I also cannot get the info from the user table, e.g the user logging the request by by adding the following join;
$query = "select r.requestid, m., a., i., b., u.*
INNER JOIN users u ON u.userid = r.userid
Please advise?
You aren't SELECTing those fields. Right now, you're only SELECTing r.requestid from the requests table. You need to add references to every field you want to echo.
As far as the User join, you just seem to be joining on the wrong field. You need to join on u.userid = r.userid. Right now, you're joining on u.itemid which doesn't exist. You'll also need to change your SELECT statement to report the fields you want (e.g. SELECT ... , u.name, u.email).
As an aside, you should avoid SELECTing table.* where possible. This can break things when you add a field to a table but don't account for that when processing the results of a query. You should try to be explicit as possible, and SELECT only the fields you want to use - e.g. SELECT users.name, users.email rather than doing SELECT users.*.

Categories