Count Rows before Group By - php

I want to count the number of articles (expected: 2) after grouping by an id but it currently returns only rows with 1 since it counts the occurrences after the GROUP BY.
article:
+-------+---------+
| id | name |
+-------+---------+
| 1 | Apple |
| 2 | Orange |
| 3 | Peaches|
+-------+---------+
article_category:
+---------------+----------------+
| article_id | category_id |
+---------------+----------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
+---------------+----------------+
Can this be done without a subquery and without using SQL_CALC_FOUND_ROWS? (I'm pretty restricted as I'm using an API endpoint). My only other idea is to simply retrieve all ids and then count them with PHP.
This is my current query:
SELECT COUNT(DISTINCT a.id) as number_articles
FROM article a
INNER JOIN article_category c ON a.id = c.article_id
WHERE c.category_id IN (1, 2, 3)
GROUP BY a.id;
Desired output:
+--------------------+
| number_articles |
+--------------------+
| 2 |
+--------------------+
Here is an SQLFiddle as suggested in the comments: http://sqlfiddle.com/#!9/8b2975/1

Based on the expected result you added now. You can remove the GroupBy, its really not achieving much here, this should work:
select count(distinct a.id)
from article a
INNER JOIN article_category c ON a.id = c.article_id
WHERE c.category_id IN (1, 2, 3)

try below solution.
select count(DISTINCT a.id) as total
from article a
INNER join article_category c on a.id = c.article_id
WHERE category_id in (1,2,3);
RESULT:
total
2

Just count the value of c.category_id instead of a.id
SELECT COUNT(c.category_id) FROM article a INNER JOIN
article_category c ON a.id = c.article_id WHERE c.category_id
IN (1, 2, 3) GROUP BY a.id;

SELECT COUNT(DISTINCT a.id)
FROM article a
INNER JOIN article_category c ON a.id = c.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;

Mysql IN query instead of multiple AND conditon

I have three mysql tables, category,students and student_category. for each student there is 1 or more category will be there and it is stored in student_category as follows.
1) Categgory
----------------------------
id | category_name
---------------------------
1 | A
2 | B
3 | C
4 | D
2) Students
--------------------------
id | name
--------------------------
1 | John
2 | Kumar
3 | Ashok
4 | Jorge
5 | Suku
-------------------------
2) student_category
-----------------------------------------
id | student_id | category_id
-----------------------------------------
1 | 1 | 2
2 | 1 | 4
3 | 2 | 3
4 | 2 | 1
5 | 3 | 2
------------------------------------------
I need to select students which contain category_id 2 and 4.
i used query as follows but it return either students contain category 2 or category 4.
select A.name from students A, student_category B where A.id=B.student_id
and B.category_id IN (2,4)
Try this query:
SELECT t1.id,
t3.name
FROM students t1
INNER JOIN student_category t2
ON t1.id = t2.student_id
INNER JOIN students t3
ON t1.id = t3.id
WHERE t2.category_id IN (2, 4)
GROUP BY t1.id
HAVING COUNT(DISTINCT t2.category_id) = 2
Explanation:
This query joins together the students and student_category tables, and then removes all records which are not category 2 or 4. This means that each student would then only have category 2 and 4 records associated with him. The HAVING clause then restricts further by requiring that a student have two distinct categories, which if true must mean that the student has both category 2 and 4.
Demo here:
SQLFiddle
try this :
select name from Students where id in (select student_id from student_category where category_id in (2,4))
your query is fine btw.
Try this one:
select
s.name
from
Students s,
Categgory c,
student_category sc
where
sc.student_id = s.id
and sc.category_id = c.id
and c.id = 2
and c.id = 4
You can check it on SQL Fiddle.
Have to take distinct student name as it will repeat if a student falls in more than one category.

Mysql select sum() from another table

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

Mysql query inside a query

First, apologies if the title doesn't match the question. Well, the problem is how to build this query...
I have a table called category It contains categories of my stuff(movies). It's like this...
--------------------------------
ID | name | parent_category
--------------------------------
1 | love | 0
2 | action | 0
3 | fear | 0
4 | passion| 1
5 | danger | 2
6 | death | 3
--------------------------------
So, as you see, each category has a parent category. Except the first 3. They're parents.
And movies table is like this...
--------------------------------
ID | name | category
--------------------------------
1 | aaaa | 1
2 | bbbbbb | 2
3 | cccc | 2
4 | ddddddd| 1
5 | eeeeee | 3
6 | fffff | 3
--------------------------------
So, what i want to do is, to select movies by parent category. Which means if I click category, love, it should select all the movies of categories that having love as the parent category.
So, how to write this in a single query ?
If the parents are only one level deep, then you can use joins:
select m.*,
coalesce(cp.id, c.id) as parent_id,
coalesce(cp.name, c.name) as parent_name
from movies m left join
categories c
on m.category = c.id left join
categories cp
on c.parent_category = cp.id;
Actually, if you only want the id, you don't need two joins:
select m.*,
(case when c.parent_id > 0 then c.parent_id else c.id end) as parent_id
from movies m left join
categories c
on m.category = c.id ;
Or, more simply:
select m.*, greatest(c.parent_id, c.id) as parent_id
. . .
to select rows filtered by condition on secend table use join in FROM clause or subquery in condition with IN or EXISTS function. To compare field with some string you can use LIKE operator.
If you are filtering based on parent_category -
SELECT b.*, a.name FROM movies b
LEFT JOIN categories a ON a.id = b.category
WHERE a.parent_category = 1;

MySQL Join two tables on multiple records

I have two tables:
Table1:
- id
- name
- table2_id1
- table2_id2
- table2_id3
Table2:
- id
- name
Table1:
id | name | table2_id1 | table2_id2 | table2_id3
1 | blabla | 1 | 2 | 3
2 | blabla2 | 2 | 3 | 1
Table2:
id | name
1 | aaa
2 | bbb
3 | ccc
I would like to display a name from Table1 and many names from Table2 which are joined, example:
*blabla | aaa | bbb | ccc*
I hope you get what I mean.
EDIT:
I tried something like this:
SELECT Table1.name, Table2.name, Table2.name, Table2.name<BR>
FROM Table1 JOIN Table2 ON<BR>
You can use left join queries:
SELECT a.name as "name", b.name as "table2_id1_name", c.name as "table2_id2_name", d.name as "table2_id3_name"
FROM Table1 a
LEFT JOIN Table2 b ON (a.table2_id1 = b.id)
LEFT JOIN Table2 C ON (a.table2_id2 = c.id)
LEFT JOIN Table2 d ON (a.table2_id3= d.id)
Hope it work as you expect. :)
SELECT a.name, b.name, c.name, d.name
FROM Table1 a, Table2 b, Table2 c, Table2 d
WHERE a.table2_id1 = b.id
AND a.table2_id2 = c.id
AND a.table2_id3= d.id

Categories