MySQL RIGHT JOIN SUM() from Table B to Info on Table A - php

Basically I have a load of product information on Table A. This include the product_id which is the common id over both tables. On Table B I have a list of votes which include product_id, username, thevote(could be +1 or -1).
So basically I want to have a table of 'Table A' with a additional column containing the SUM of all the votes for that product_ID. I am sure there is an easy way to do this. Which i think is using 'right join'.
I still want it to list all the products in Table A regardless if they have a single +1 or -1 vote.
Many thanks in advance peoples!

You could use group by statement and left join like:
select productName, sum(vote) as productVoteSum
from `products` p
left join `products_votes` pv on p.id = pv.productId
where productName like '%chocolat%'
group by p.id
order by productName;

You can do a LEFT JOIN (that goes through all the information on tableA and puts the SUM in the ones that have the matching product_id on tableB), then you add the SUM(b.thevote) and group by the remaining columns
SELECT a.product_id,a.productName,SUM(b.thevote)
FROM tableA a
LEFT JOIN tableB b ON a.product_id = b.product_id
GROUP BY a.product_id, a.productName

SELECT a.*, SUM(b.votes) FROM TableA a LEFT JOIN TableB b ON a.prouct_id=b.product_id
GROUP BY a.product_id

Related

I want to use JOIN for a query and I want to show only the name of the product with the image

I'm practicing with queries and I have a question about JOIN.
I have these 2 tables:
**PRODUCTS**:
id
name
description
**PRODUCT_IMAGES**
id
product_id
image_link
And I want to use JOIN to combine these 2 table where I only want to see the name of the product with the specific image that is linked with the id.
I try to to that with this QUERY:
SELECT * FROM `product_images`
LEFT JOIN `products`
ON `product_images`.`products.id` = `products`.`id`;
The problem now is that I get all the information, but I only want to see the name and the image.
You have an error with product_images.id as it should be like "product_images.product_id" , I fixed this, kindly use this query.
SELECT products.name, product_images.image_link FROM `product_images`
INNER JOIN `products`
ON `product_images`.`product_id` = `products`.`id`;
Change * to name, image_link:
SELECT name, image_link FROM `product_images`
LEFT JOIN `products`
ON `product_images`.`products.id` = `products`.`id`;
SELECT products.id,products.name FROM `product_images`
LEFT JOIN `products`
ON `product_images`.`products.id` = `products`.`id`;
Instead of * you can give the column names comma separated.
You may choose LEFT JOIN or INNER JOIN as per your need.
Select the desired columns in the select statement. It's a best practice to name the table and column together. Otherwise if a column exists with the same name in both tables it will throw an error.
SELECT `products`.`name`,`product_images`.`image_link`
FROM `product_images`
LEFT JOIN `products`
ON `product_images`.`products.id` = `products`.`id`;
Simple use inner join
SELECT
p.name,
i.image_link
FROM
products p
JOIN
product_images i USING(product_id)
If you are sure, you have data in both tables then use the below
SELECT P.name, PI.image_link FROM product_images PI
inner JOIN products P
ON P.id = PI.product_id
If you are sure you have data in product table but might be not in product_image then use below
SELECT P.name, PI.image_link FROM products P
left JOIN product_images PI
ON P.id = PI.product_id

Writing complex SQL query with 4 tables

I have 4 tables from which i want to output information with a single query and i'm not sure how to do that.
• From table1 i want to get all the records
• For each record from table1 i want to take out the SUM from field1 from all records in table2 on a matching id taken from table1
• For each record from table1 i want to take out the SUM from field1 from all records in table3 on a matching id taken from table1
• For each record from table1 i want to take out the value of a single record from table4 on a matching id taken from table1
EDIT:
Here is how i think the graphic for my request should look:
Here's my working code:
SELECT DISTINCT
i.id,
i.dateCreated,
i.dateBilled,
i.dateCompleted,
i.userId,
i.type,
i.status,
i.truck,
i.poNumber,
i.total,
i.billtoId,
i.shiptoId,
i.invoiceNumber,
i.loadNumber,
SUM(p.amount) as amountpaid,
c.name as billtoName
FROM `invoices` as i
LEFT JOIN `invoice_payments` as p ON i.id = p.invoice
RIGHT JOIN `companies` as c ON c.id = i.billtoId
GROUP BY i.id, i.invoiceNumber
You can see how i managed to get the SUM from all payments on my invoices with a left join. I'm trying to do the same for i.total, but as soon as i add another LEFT JOIN my calculations come up wrong and the result in amountpaid doubles
You can write this query with subqueries in the SELECT statement:
SELECT id,
(SELECT sum(field1) FROM t2 WHERE t2.idfrom1=t1.id) AS firstSum,
(SELECT sum(field1) FROM t3 WHERE t3.idfrom1=t1.id) AS secondSum,
(SELECT min(field1) FROM t4 WHERE t4.id=t1.f2 LIMIT 1) AS singleRecord
FROM t1
This is the idea, you just have to adapt it to your schema.
edit: updated from the drawing

Mysql Ranking based on Category and Branch

I'm having a hard time figuring out and trying how to fix this.
Can you help me give a logic or idea how can get the ranking of each category for each branch based on sales?
For example:
Rank 1 for branch_code_id = 9 is Accicular since it has 300,000 sales
Rank 2 for branch_code_id = 9 is WLO since it has only 200,000
sales.
Same as with other branches. I only need the rank of category for each branch_code_id.
I can't figure out how to loop this one. Rank will be placed in the "r" column as you can see in the excel output.
By the way, here's the sql statement i used to get the result you see in the screenshot.
SELECT
a.id,
a.date,
a.branch_code_id,
SUM(b.amount),
c.category
FROM
sales_add_h AS a
INNER JOIN sales_add_i AS b ON a.id = b.sales_h_id
INNER JOIN control_panel_item_create AS c ON b.item_code_id = c.id
GROUP BY c.category, a.branch_code_id, b.amount
ORDER BY SUM(b.amount) DESC
Thanks Guys!
Try this query
SELECT
#rn:=if(#prv=branch_code_id, #rn+1, 1) as rId,
#prv:= branch_code_id as branch_code_id,
val,
id,
date,
category
FROM
(SELECT
a.id,
a.date,
a.branch_code_id,
SUM(b.amount) as val,
c.category
FROM
sales_add_h AS a
INNER JOIN
sales_add_i AS b ON a.id = b.sales_h_id
INNER JOIN
control_panel_item_create AS c ON b.item_code_id = c.id
GROUP BY
c.category, a.branch_code_id, b.amount
ORDER BY
a.branch_code_id, SUM(b.amount) DESC)tmp
JOIN
(SELECT #rn:=0, #prv:=0)t
SQLFIDDLE to understand how ranking works.
I have done ranking for each branch_id as you have mentioned, if you want to rank for each category in a particular branch than you need to add another variable which stores the category and compare it within the if clause and also need to sort data within inner query accordingly order by c.category, a.branch_code_id, SUM(b.amount) DESC

mysql query dont gets all posts

I have a MYSQL query who have to list all post i want it to post. But it dont do it. It shows posts when i have more then one post in the table "meaOrder" with the same "ordCode". But when i have only on post in meaOrder, i don't show it. What can i do?
SELECT koden, wish, rnamn, bild, pris, cname, onsktext
FROM (
SELECT m.wishText as onsktext, m.meaOID as midn, m.ordcode as koden, w.wish as wish, r.meaName as rnamn, r.meaImg as bild,
r.meaPrice as pris, k.catName as cname from cats k, meals r, wishes w,
meaOrder m
join orders c on c.ordNR=4401
WHERE c.ordStatus=1 AND m.ordNR=c.ordNR AND m.meaID=r.meaID AND m.wishesID=w.id
AND r.catID=k.catID
) T
GROUP BY koden, rnamn, bild, pris, cname
ORDER BY midn DESC
TABLE orders
http://grab.by/m74E
TABLE meaOrder http://grab.by/m74Q
Try replacing the JOIN with RIGHT JOIN in this case. The difference is explained at JOIN Syntax page in MySQL docs . In short - JOIN returns row only if there are corresponding rows in both joined tables (inner join). LEFT JOIN / RIGHT JOIN return all rows from one of the tables and corresponding row if it exists from the other table (those are outer joins)
Do you need a subselect?
This seems to cover it:-
SELECT m.ordcode AS koden, w.wish AS wish, r.meaName AS rnamn, r.meaImg AS bild, r.meaPrice AS pris, k.catName AS cname, m.wishText AS onsktext
FROM cats k
INNER JOIN meals r ON r.catID = k.catID
INNER JOIN meaOrder m ON m.meaID = r.meaID
INNER JOIN wishes w ON m.wishesID = w.id
INNER JOIN orders c ON m.ordNR = c.ordNR
WHERE c.ordStatus = 1
AND c.ordNR = 4401
GROUP BY m.ordcode, r.meaName, r.meaImg, r.meaPrice, k.catName
ORDER BY midn DESC

Getting the maximum value from interrelated MySQL tables

I am trying to unify a pair of queries with a LEFT JOIN, so that I can perform an ORDER BY on a desired column.
Table A has an exclusive one-to-many relationship with Table B, and table B has an exclusive one-to-many relationship with Table C.
I want to get the maximum value of a column in Table C, for each row in Table A.
what I used to have was:
$tableA = SELECT * FROM tableA;
for each row in $tableA {
$maxValue = SELECT MAX(value) FROM tableC WHERE tableB_id IN (SELECT tableB_id FROM tableB WHERE tableA_id={$row['tableA_id']}) GROUP BY tableB_id;
}
and now I'm thinking along the lines of:
SELECT * FROM tableA LEFT JOIN (SELECT tableA_id, MAX(max_c_value) FROM (SELECT tableB_id, MAX(value) max_c_value FROM tableC GROUP BY tableB_id) t GROUP BY tableA_id) USING(tableA_id)
but I know that's gibberish. I am not sure where to go from here.
I'm finding it hard to explain the problem, sorry.
SELECT A.ID, MAX(C.MyField) as CField
FROM A
LEFT OUTER JOIN B
ON A.ID = B.A_ID
LEFT OUTER JOIN C
ON B.ID = C.B_ID
GROUP BY A.ID
You will get null value for CField if there is no rows corresponding.
select max(table3.field),table1.field from table1
join table2 on table1.id=table2.table1_id
join table3 on table2.id = table3.table2_id
group by table1.field
You were closer on the first try I think. You want something like this:
SELECT MAX(tableC.cValue) FROM tableA
LEFT JOIN tableB
ON tableA.tableA_id = tableB.tableA_id
LEFT JOIN tableC
ON tableB.tableB_id = tableC.tableB_id
http://www.w3schools.com/sql/sql_join.asp
I have managed to solve it on my own, only to come back here and find I was making things far too complicated for myself, getting lost in a sea of tables!
This code did actually work, but I have already replaced it with the simpler code suggested above:
SELECT * FROM A LEFT JOIN (
SELECT A_ID, MAX(val) FROM (
SELECT * FROM B LEFT JOIN (
SELECT B_ID, MAX(val) val FROM C GROUP BY B_ID
) x USING(B_ID)
) y GROUP BY A_ID
) z USING(A_ID);

Categories