SQL Query with Join, Count and Where - sql

I have 2 tables and am trying to do one query to save myself some work.
Table 1: id, category id, colour
Table 2: category id, category name
I want to join them so that I get id, category id, category name, colour
Then I want to limit it so that no "red" items are selected (WHERE colour != "red")
Then I want to count the number of records in each category (COUNT(id) GROUP BY (category id).
I have been trying:
SELECT COUNT(table1.id), table1.category_id, table2.category_name
FROM table1
INNER JOIN table2 ON table1.category_id=table2.category_id
WHERE table1.colour != "red"
But it just doesn't work. I've tried lots of variations and just get no results when I try the above query.

You have to use GROUP BY so you will have multiple records returned,
SELECT COUNT(*) TotalCount,
b.category_id,
b.category_name
FROM table1 a
INNER JOIN table2 b
ON a.category_id = b.category_id
WHERE a.colour <> 'red'
GROUP BY b.category_id, b.category_name

SELECT COUNT(*), table1.category_id, table2.category_name
FROM table1
INNER JOIN table2 ON table1.category_id=table2.category_id
WHERE table1.colour <> 'red'
GROUP BY table1.category_id, table2.category_name

I have used sub-query and it worked great!
SELECT *,(SELECT count(*) FROM $this->tbl_news WHERE
$this->tbl_news.cat_id=$this->tbl_categories.cat_id) as total_news FROM
$this->tbl_categories

Related

Show max to min count in SQL group by

I have a table with id, Name columns.
When selecting I want to group by on Name column (but show all records NO summary), and show result count max number of in one grouping to min number of one grouping.
SELECT Table1.id, Table1.name
FROM Table1
GROUP BY Table1.id, Table1.name;
This is table:
My idea:
but I get this result:
One approach uses a join to a subquery which finds the counts for each name:
SELECT a.name, a.ID
FROM Table1 AS a
INNER JOIN
(
SELECT name, COUNT(*) AS cnt
FROM Table1
GROUP BY name
) AS b
ON a.name = b.name
ORDER BY
b.cnt DESC,
a.ID;
When you group by ID you create a separate group for each element, because each element has a unique ID. To get the count of each name group, you will want to create a grouping by name and then join it with your original table so the values are preserved. Something like:
WITH Counts (name, cnt) AS
(SELECT name, COUNT(*)
FROM Table1
GROUP BY name)
SELECT Table1.id, Table1.name
FROM Table1, Counts
INNER JOIN Counts
ON Table1.name = Counts.name
ORDER BY Counts.cnt DESC
Oh, I see. You an use a subquery in the order by:
select t.*
from t
order by (select count(*) from t t2 where t2.name = t.name) desc, name;
Note that name is the second order by key. If two names have the same counts, then this keeps all the rows for a given name together.

oracle12c,sql,difference between count(*) and sum()

Tell me the difference between sql1 and sql2:
sql1:
select count(1)
from table_1 a
inner join table_2 b on a.key = b.key where a.id in (
select id from table_1 group by id having count(1) > 1
)
sql2:
select sum(a) from (
select count(1) as a
from table_1 a
inner join table_2 b on a.key = b.key group by a.id having count(1) > 1
)
Why is the output not the same?
The queries are not even similar. They are very different. Let's check the first one:
select count(1)
from table_1 a
inner join table_2 b
on a.key = b.key
where a.id in (
select id from table_1 group by id having count(1) > 1
) ;
You are first making an inner join:
select count(1)
from table_1 a
inner join table_2 b
on a.key = b.key
In this case, you can use count(1), count(id), count(*), it's equivalent. You are counting the common elements in both tables: those ones that have in common the key field.
After that, you are enforcing this:
where a.id in (
select id from table_1 group by id having count(1) > 1
)
In other words, that every "id" of the table_1 must be at least two times in the table_1 table.
And lastly, you are doing this:
select count(1)
In other words, counting those elements. So, translated into english you have done this:
get every record of table_1 and pair with records of table_2 for the id, and get only those that match
for the result above, filter out only the elements whose id of the table_1 appears more than one time
count that result
Let's see what happens with the second query:
select sum(a) from (
select count(1) as a
from table_1 a
inner join table_2 b
on a.key = b.key
group by a.id
having count(1) > 1
);
You are making the same inner join:
select count(1) as a
from table_1 a
inner join table_2 b
on a.key = b.key
but, you are grouping it by the id of the table:
group by a.id
and then filtering out only those elements who appear more than one time:
having count(1) > 1
The result so far are a set of records that have in common the key field in both tables, but grouped by the id: this means that only those fields that are at leas two times in the table_b are outputed of this join. After that, you group by id, collapsing those results into the table_1.id field and counting the result. I presume that very few records will match this strict criteria.
And lastly, you sum all those set.
When you use count(*) you count ALL the rows. The SUM() function is an aggregate function that returns the sum of all or distinct values in a set of values.

Count the Same Columns in Two Differnt Table

I am looking for a way to count for the same column in two different tables.
So I have two tables, table1 and table2. They both have the column "category". I want to find a way to count category for these two tables and show as the result below.
I know how to do this individually by
select category, count(category) as cnt from table1
group by category
order by cnt desc
select category, count(category) as cnt from table2
group by category
order by cnt desc
Not sure how to combine the two into one.
The expected result should be like below. Please note there are some "category" in table1 but not in table2 or vice versa, for example category c and d.
table1 table2
a 4 2
b 4 3
c 3
d 4
One method is full join:
select coalesce(t1c.category, t2c.category) as category,
t1c.t1_cnt, t2c.t2_cnt
from (select category, count(*) as t1_cnt
from table1
group by category
) t1c full join
(select category, count(*) as t2_cnt
from table2
group by category
) t2c
on t1c.category = t2c.category;
You need to be very careful that you aggregate before doing the join.

Joining tables + SUM & GROUP BY function

I'm struggling in joining tables together with SUM and GROUP BY function. The query below works fine:
select ID, sum(amount)
from table1
group by ID
having sum(amount) between 1000 and 10000
As table1 only includes customer ID, I also need to join table CUSTOMERS, which contain customer name (column NAME). Following query will not work for me anymore:
select ID, name, sum(amount)
from table1
left join customers on table1.ID = customers.ID2
group by ID
having sum(amount) between 1000 and 10000
Ditching SUM and GROUP BY functionality does "fix" the issue as also column NAME will be available in the result, however I still need to sum and group the AMOUNT based on ID. How should I join the other table in this case to also present field NAME from table CUSTOMERS?
Column NAME or expression in SELECT list not valid'
is currently given as error message.
It needs to be in the group by:
select t1.ID, c.name, sum(t1.amount)
from table1 t1 left join
customers c
on t1.ID = c.ID2
group by t1.ID, c.name;
Note the use of table aliases.
Add "name" in group by clause
select table1.ID, customers.name, sum(table1.amount) amount
from table1,customers on table1.ID = customers.ID2
group by table1.ID,customers.name
try it
select t.ID, c.name, sum(t.amount)
from table1 t
left join customers c on table1.ID = customers.ID2
group by t.ID, c.name
having sum(t.amount) between 1000 and 10000
or without having depends on your requirement

Join two tables and retrieve relevant data and calculate the result

We have two tables table1 and table2
Table 1
Table 2
We need the resultant table as :
All this should be done in a single SQL query
Thanks in advance.
I think you can make it without the second query, I tested it and returned your expected values.
select table_2.id_pro,
product_name,
SUM(1) as Quantity,
priceprod,
SUM(1) * priceprod as 'quantity * priceprod'
from Table_2
inner join Table_1 t1 on table_2.id_pro = t1.id_pro
group by table_2.id_pro, product_name, priceprod
And my SqlFiddle test http://sqlfiddle.com/#!3/08c2ef/1
I believe this should be what you need, or fairly close anyway! You need to group up your results from your first table to get your quantity value and then join those results to your second table to be able to create your desired output.
SELECT t1.id_pro,
t2.product_name,
s.Quantity,
t2.priceperprod,
s.Quantity * t2.priceperprod
FROM table_2 t2
INNER JOIN (
SELECT COUNT(*) AS Quantity,
t.id_pro
FROM table_1 t
GROUP BY t.id_pro
) t1 ON t2.id_pro = t1.id_pro
i believe that this is correct, i just JOIN the two tables AND used group by then count how many records each group, i hope this will help you, thanks.
SELECT
A.id_pro,
A.product_name,
(count(*)) AS Quantity,
A.priceperprod,
(COUNT(*) * A.priceperprod) AS Total
FROM table_2 A
LEFT JOIN table_1 B
ON B.id_pro = A.id_pro
GROUP BY A.id_pro
Guess this should be helpful to you.
SELECT A.PRODUCT_CODE, A.PRODUCT_NAME, B.QUANTITY,
A.PRICE PRICE_PER_PRODUCT,
(B.QUANTITY * A.PRICE) TOTAL_PRICE FROM
TABLE2 A,
(SELECT X.PRODUCT, COUNT(X.PRODUCT) QUANTITY FROM TABLE1 AS X
GROUP BY X.PRODUCT) as B
WHERE A.PRODUCT_CODE = B.PRODUCT
ORDER BY A.PRODUCT_CODE
Am doing following :
Taking the entire TABLE2 aliased as A
Getting the products and its corresponding count using group by and aliasing it as B
Selecting corresponding fields from table_Aliases A and B provided A's ProductCode and B's Products are same.