Mysql select sum() from another table - php

I have this tables :
Table: Articles
id | title | display |
-----------------------------------
1 | Fkekc | 1 |
2 | ldsdf | 1 |
3 | OTRld | 0 |
4 | QCRSA | 1 |
Table: Likes
id | article_id | like | type
----------------------------------------
1 | 1 | 121 | 1
2 | 1 | 652 | 2
3 | 2 | 12 | 1
4 | 1 | 5 | 3
i want get this result:
Article [1] => 778
Article [2] => 12
Article [3] => 0
Article [4] => 0
I use LEFT JOIN between two tables but this return records per likes table. so i get three record of article 1
My code:
SELECT articles.*,likes.like FROM `articles` LEFT JOIN `likes` ON articles.id=likes.article_id WHERE display='1'
I know that i must use SUM() but i didn't know how use it
With your answers i find that i must use this:
SELECT articles.*, sum(likes.like) as likesSum FROM `articles` LEFT JOIN `likes`ON articles.id=likes.article_id WHERE display='1' GROUP BY articles.id
But i want to set filter in query. so use this :
SELECT articles.*, sum(likes.like) as likesSum FROM `articles` LEFT JOIN `likes`ON articles.id=likes.article_id WHERE display='1' && likesSum>='100' GROUP BY articles.id
But above code doesn't return any result

This is your query
SELECT articles.*,COALESCE(sum(likes.like),0) as total_like FROM
`articles` LEFT JOIN `likes` ON articles.id=likes.article_id group by
articles.id
Output is

SELECT articles.*, sum(likes.like) as likesSum FROM `articles` LEFT JOIN `likes`ON articles.id=likes.article_id WHERE display='1' GROUP BY articles.id

This should work for you perfectly..
SELECT articles.id, sum(likes.like) from articles left join likes on (articles.id=likes.article_id) group by articles.id order by articles.id
See the use of SUM() with GROUP BY

This visual representation is great to understand the joins: http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins

You did everything right but only one this missing. You should have used group by
SELECT articles.*, likes.like
FROM `articles`
LEFT JOIN `likes` ON articles.id = likes.article_id
WHERE display = '1'
GROUP BY likes.article_id

Related

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;

Connecting 3 MySQL tables, what am I doing wrong

I have a 3 tables with the following data in MySQL
tags table
id | groupId | name |
-----------------------------
1 | 1 | tag1 |
2 | 1 | tag2 |
3 | 1 | tag3 |
4 | 1 | tag4 |
groupId column here is unimportant right now.
practice table
id | name |
----------------------
1 | practice 1 |
2 | practice 2 |
3 | practice 3 |
4 | practice 4 |
and a bridge between the two (practiceTag table)
id | practiceId | tagId |
-----------------------------------
1 | 1 | 1 |
2 | 1 | 2 |
3 | 1 | 3 |
4 | 2 | 1 |
But when I try to use the query:
SELECT practice.name
FROM practice
INNER JOIN practiceTag ON practiceTag.practiceId = practice.id
INNER JOIN tags ON practiceTag.tagId = tags.id
WHERE (tags.id = "1"
AND tags.id = "2"
AND tags.id = "3")
it doesn't return anything. And thats ok, since I know my query is kinda messed up. But thats as closest as I can get to show you, what I would like my query to do.
I've searched the forums and find out that I can use a group_concat. But I just can't get it to work.
Any help would be appreciated.
Thanks, Sebastian
I think your tags.id column is integer not string, so your sql query would be like this:
SELECT practice.name
FROM practice
INNER JOIN practiceTag ON practiceTag.practiceId = practice.id
INNER JOIN tags ON practiceTag.tagId = tags.id
WHERE tags.id in (1,2,3);
You in clause not and
SELECT practice.name
FROM practice
INNER JOIN practiceTag ON practiceTag.practiceId = practice.id
INNER JOIN tags ON practiceTag.tagId = tags.id
WHERE tags.id in ( '1', '2', '3') ;
if the id is numeric
SELECT practice.name
FROM practice
INNER JOIN practiceTag ON practiceTag.practiceId = practice.id
INNER JOIN tags ON practiceTag.tagId = tags.id
WHERE tags.id in ( 1, 2, 3) ;
the query is equivalent
SELECT distinct practice.name
FROM practice
INNER JOIN practiceTag ON practiceTag.practiceId = practice.id
INNER JOIN tags ON practiceTag.tagId in (1,2,3)
And if you want only the practice.name when all the 3 tagsId match the you should use temp table for getting the join table
SELECT distinct practice.name
FROM practice
inner join (
select practiceId from
( select distinct practiceTag.practiceId as praticeId, practiceTag.tagId as tagId
from tags ) as t1
where tagId in (1,2,3)
having count(*) > 2
group by praticeId ) as t2;
In your WHERE part you ask for results that have id 1, 2 and 3 at the same time.
Replace the AND in your WHERE with OR

Get result from three tables using join from which one table contain multiple result

I have three tables with the following columns and data:
table_one
id | balance
100 | 10.00
101 | 5.00
102 | 8.00
table_two
id | number
100 | 0890980980
100 | 7657657655
101 | 7657657656
102 | 1231231233
table_three
id | name | active
100 | nameOne | 1
101 | nameTwo | 0
102 | namrThree | 1
Now my query will be
Query 1. SELECT * FROM table_one WHERE balance <= 8
Query 2. SELECT number(only first_matched_row) FROM table_two WHERE table_one.id = table_two.id
Query 3. SELECT name FROM table_three WHERE table_three.id = table_one.id AND table_three.active = 1
How can I join these three queries and get a single query.
Please note that table_two will get multiple rows so I want take the first matched row and omit the rest where table_two.id matches.
Expected Result:
id | name | number
100 | nameOne | 0890890890
102 | nameThree | 1231231233
SOLVED ANSWER:
Select onetwo.id, three.name, two.number from
(Select two.id from
(SELECT id as id1 FROM table_one WHERE balance <= 8)one
inner join
table_two two on one.id1 = two.id
)onetwo
inner join
table_two two on two.id=onetwo.id
inner join
table_three three on three.id = onetwo.id AND three.active = 1 group by two.id
Would you try:
Select onetwo.id, three.name, onetwo.number from
(Select two.id from
(SELECT id as id1 FROM table_one WHERE balance <= 8)one
inner join
table_two two on one.id1 = two.id
)onetwo
inner join
table_three three on three.id = onetwo.id AND three.active = 1 group by onetwo.id
You can have more elegant queries using advanced RDBMS, but not with MySQL unfortunately.

Group by 2 columns regardless of order

The following query
select a.message, a.sender_id, a.rec_id, a.id, a.is_seen, b.total_msg, b.last_id, users.name
from tbl_message a left join users on (users.id=a.sender_id)
inner join
(select sender_id, rec_id, max(id) last_id, count(*) total_msg
from tbl_message group by sender_id,rec_id
)b on a.id=b.last_id
order by a.id desc
gives the result as below:
+----------------------------+-----------+--------+----+---------+-----------+---------+------+
| message | sender_id | rec_id | id | is_seen | total_msq | last_id | name |
+----------------------------+-----------+--------+----+---------+-----------+---------+------+
| latest testing l5 aug | 2 | 1 | 12 | 0 | 5 | 12 | B |
| testing | 1 | 2 | 11 | 1 | 3 | 11 | A |
| this msg of A | 1 | 3 | 9 | 0 | 1 | 9 | A |
| this is again 3rd msg of C | 3 | 1 | 6 | 1 | 3 | 6 | C |
+----------------------------+-----------+--------+----+---------+-----------+---------+------+
I want the result as:
For sender_id/rec_id = 1 or 2 id = 12 and for sender_id/rec_id = 1 or 3 id = 9
It sounds like you want to group rows by the sender_id,rec_id participants pair regardless of which order they appear in (i.e. sender_id,rec_id or rec_id,sender_id should be part of the same group).
If so, change your group by from
group by sender_id, rec_id
to
group by least(sender_id,rec_id), greatest(sender_id,rec_id)
Using greatest and least will ensure that each conversation will be grouped by the participants regardless of which order they appear in.
Looks like you need to join with all the grouped columns
Try this
SELECT a.message
,a.sender_id
,a.rec_id
,a.id
,a.is_seen
,b.total_msg
,b.last_id
,users.NAME
FROM tbl_message a
LEFT JOIN users ON (users.id = a.sender_id)
INNER JOIN (
SELECT sender_id
,rec_id
,max(id) last_id
,count(*) total_msg
FROM tbl_message
GROUP BY sender_id
,rec_id
) b ON a.sender_id=b.sender_id and a.rec_id=b.rec_id and a.id = b.last_id
ORDER BY a.id DESC
I think you need to remove one column from the GROUP BY clause of the derived table (subquery)
select a.message, a.sender_id, a.rec_id, a.id, a.is_seen, b.total_msg, b.last_id, users.name
from tbl_message a left join users on (users.id=a.sender_id)
inner join
(select sender_id, rec_id, max(id) last_id, count(*) total_msg
from tbl_message group by sender_id
)b on a.id=b.last_id
order by a.id desc
I would expect this to result in rows only for the following
SenderID ID
2 12
1 9
3 6

how to select sum, and count from diffrent tables using multiple joins

I need to generate some big data from many tables, regarding filters, at there also i need to get the sum of some columns, and also counts of rows like example
i have 5 records
ID | NAME | DELETED
1 | A | 1
2 | A | 0
3 | A | 1
4 | B | 1
5 | C | 1
I have the query,
SELECT p.name, sum(p.deleted) as del, count(p.id) as numbers from products as p
join other AS b ON p.id=b.id
The output i need is,
The sum of deleted records
NAME | Deletion | Count
A | 2 | 3
B | 1 | 1
C | 1 | 1
Try this ::
SELECT
p.name,
sum(p.deleted) as del,
count(id) as numbers
from products as p
join other AS b ON p.id=b.id
group by p.name
You should not need to join to get your result. This should work:
SELECT name, sum(deleted), count(1)
FROM products
GROUP BY name
SELECT name,
SUM(CASE WHEN deleted = 1 THEN 1 ELSE 0 END) Deletion,
COUNT(*) `COunt`
FROM products
GROUP BY name
OR
SELECT name,
SUM(deleted) Deletion,
COUNT(*) `COunt`
FROM products
GROUP BY name;
SQLFiddle Demo (both queries)

Categories