sql select rows with exact filters - sql

product_id
filter_id
1
10
1
5
2
15
3
10
4
10
4
20
Let's say I chose filters with 10 and 5 ids. So there is only one match -> product with product_id = 1. Because only this product maches 10 and 5. How can I take this product with sql?
Select product_id from product where filter_id in (5,10)
gives me all products which have 5 OR 10. I need to check if they match both filters..

You can use group by and having:
Select product_id
from product
where filter_id in (5, 10)
group by product_id
having count(*) = 2;

You can also use join:
SELECT P.product_id
FROM product P
JOIN product P2
ON P.product_id = P2.product_id
WHERE P.filter_id = 5 AND P2.filter_id = 10

Related

Return Records that span over two tables in a 1 to many relationship with multiple criteria on the many side

I am trying to get a count of records of data that spans over three tables. I have a table of products, a table of groups and a table showing which groups a product is in. As below:
Product
Product_ID
Product_Name
1
A Product
2
Another Product
Group
Group_ID
Group_Name
10
Group A
20
Group B
30
Group C
40
Group D
Product Grouping
Product_ID
Group_ID
1
10
1
20
1
30
2
20
2
40
3
50
I am trying to write a query that will, given the condition of group ids of say for example (10,20,30), it will return product 1. And if I give group ids of say (20), it will return product 1 and product 2
I have tried:
select * from product_grouping
where group_id = 10 and group_id = 20 and group_id = 30
Use aggregation and having:
select pg.group_id
from product_grouping pg
where pg.group_id in (10, 20 30)
group by product_id
having count(*) = 3;
If the product groupings can be duplicated, use having count(distinct pg.group_id) = 3.

Group by with set of values in PostgreSQL

I have a product table:
productid product
1 A-110
2 B-110
3 C-400
4 D-401
And orderditems table:
orderitemid productid qty
1 1 10
2 2 10
3 3 10
4 3 10
5 4 10
I can group by based on product as:
select productid, sum(qty)
from ordereditems
group by productid
Which gives:
1 10
2 10
3 20
4 10
However for this query productid 1 & 2 , 3 & 4 are the same.
Meaning that I want to see:
1 + 2 20
3 + 4 30
Basically I want the query to understand that 1 & 2 are the same group and 3 & 4 are the same group.
How can i do that?
Edit:
Products 1 & 2 , 3 & 4 are not the same. However they are of the same family... What I want is to see how much we sell per family and not per product.
This is why the desired out put is:
1 + 2 20
3 + 4 30
A hacky version if you know that 1&2 are the same and 3&4 are the same, and those are the only things the same.
select
case
when productid in (1,2) then '1 + 2'
when productid in (3,4) then '3 + 4'
else productid
end as product_ids, sum(qty)
from ordereditems
group by
case
when productid in (1,2) then '1 + 2'
when productid in (3,4) then '3 + 4'
else productid
end
A better approach is to record in the database that two products are the same. Either by linking the duplicated products (2,4) to the product they're the same as (1,3) or by creating a new table family etc. and recording that products 1,2 are related to the same family.
family
familyid name
1 1+2
2 3+4
Extend product table
productid product familyid
1 A-110 1
2 B-110 1
3 C-400 2
4 D-401 2
then you can group on family
select f.name, sum(qty)
from ordereditems oi
inner join product p on oi.productid = p.productid
inner join family f on p.familyid = f.familyid
group by f.name
Pls add a GroupID/Category field to your table.
productid product GroupID
1 A-110 A
2 B-110 A
3 C-400 B
4 D-401 B
Then use the query
select GroupID, sum(qty) as Sold
from ordereditems
group by GroupID
This will represent as group sale as if you have more than 10 products in a group your productid will make complicity to understand.
If it works for you pls mark as helpful.. :)

SQL/Microsoft Access

I am trying to figure out this problem but, it's already taking me a few days and I cant seem to solve it.
The questions demands:
Display a list of products (show ProductID and ProductDescription as the first two columns), the number of times each product has been ordered (the third column), and the total quantity each product has been ordered over all orders (the forth column).
The Database:
**Product_T** **OrderLine_T**
ProductID ProductDescription ProductID OrderedQuantity
1 End Table 1 2
2 Coffe Table 2 2
3 Computer Desk 4 1
4 Entertainment Center 3 5
5 Writers Desk 3 3
6 8-Drawer Desk 6 2
7 Dining Table 8 2
8 Computer Desk 4 4
4 1
5 2
7 2
1 3
2 2
3 3
8 3
4 2
7 3
8 10
Just a JOIN and GROUP BY
SELECT p.ProductID,
p.ProductDescription,
COUNT(*) AS time_ordered,
SUM(o.OrderedQuantity) AS qty_ordered
FROM Product_T as p
LEFT JOIN OrderLine_T AS o
ON p.ProductID = o.ProductID
GROUP BY p.ProductID,
p.ProductDescription;
Try this:
SELECT t1.ProductID,
t1.ProductDescription,
COALESCE(t2.num_times_ordered, 0) AS num_times_ordered,
COALESCE(t2.total_quantity, 0) AS total_quantity
FROM Product_T t1
LEFT JOIN
(
SELECT ProductID,
COUNT(*) AS num_times_ordered,
SUM(OrderedQuantity) AS total_quantity
FROM OrderLine-T
GROUP BY ProductID
) t2
ON t1.ProductID = t2.ProductID
The answer given by #GurV is more concise than this and works for this particular problem, but in general you would need to use a subquery to obtain stats from the OrderLine-T table, assuming that you wanted to include non-aggregate columns from Product_T in your report.

How to limit SQL query which uses join with Many-to-Many relationships? [duplicate]

I'm implementing pagination on my BD. My problem is when I want limit the SELECT statement but not the JOIN. Example, a product can got many prices:
SELECT * FROM product
LEFT JOIN price ON product.id == price.id_product
LIMIT 20
But I want to get 20 products with each one with their prices. How I can limit the statement SELECT, but not LEFT JOIN.
Example:
product price.id price.id_pruct price.price
1 1 1 50
2 2 1 30
3 3 1 40
4 1 20
5 2 30
SELECT * FROM product
LEFT JOIN price ON product.id == price.id_product
LIMIT 3
Return:
product price.id id_prodcut price
1 1 1 50
1 2 1 30
1 3 1 40
But I Want
product price.id id_prodcut price
1 1 1 50
1 2 1 30
1 3 1 40
1 4 1 20
2 5 2 30
3 . . .
Three products (limit 3)
Thanks. I hope you can help me.
Modify your query to limit the number of product rows before joining it to the price table. This means we want to to join the results of a query to a table, or in other words, we write a query containing a subquery:
SELECT *
FROM (
SELECT *
FROM product
ORDER BY id_product
LIMIT 3
) p
LEFT JOIN price ON p.id = price.id_product
Hope that helps.
I would write a subquery to get the three first products (or whatever condition you choose) like this:
SELECT id
FROM product
ORDER BY id
LIMIT 3;
Once I have that, I can select everything from the price table as long as the id is in that subquery. You can do this using a join:
SELECT p.*
FROM price p
JOIN(
SELECT id
FROM product
ORDER BY id
LIMIT 3) tmp ON tmp.id = p.product_id;
Here is an SQL Fiddle example using your sample data, and I also added a row that won't be returned so you can see that it works.

Microsoft SQL - Counting total of matching values in other table

I have a SQL data scructure like this.
Table 1
http://pbrd.co/1x6TAl3
Table 2
http://pbrd.co/1x6TIRw
I'm trying to count the number of times each item_num has been sold based on the item_qty value in the second table.
Each item_num can appear multiple times in the second table.
I need a way to add the total item_qty for each associated item_num and output it to show how many times an item has been sold.
The correct output ordering by total quantity sold in descending order should look like this.
item_num: 4 7 6
qty_sold: 11 5 4
Try this:
SELECT
a.item_num
, SUM(b.item_qty) as "qty_sold"
FROM
Table1 a
LEFT JOIN
Table2 b
ON a.item_num = b.item_num
GROUP BY
a.item_num
ORDER BY
qty_sold DESC
SELECT A.Item_num , A.Item_name , sum(B.Item_Qty) from Table1 as A inner join Table2 as B
on A.Item_num=B.Item_num
group by A.Item_num , A.Item_name
result:
item_num item_name Item_qty
1 A 1
2 B 1
4 D 11
6 F 4
7 G 5