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

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.

Related

Merge row values based on other column value

I'm trying to merge the values of two rows based on the value of another row in a different column. Below is my based table
Customer ID
Property ID
Bookings per customer
Cancellations per customer
A
1
0
1
B
2
10
1
C
3
100
1
C
4
100
1
D
5
20
1
Here is the SQL query I used
select customer_id, property_id, bookings_per_customer, cancellations_per_customer
from table
And this is what I want to see. Any ideas the query to get this would be? We use presto SQL
Thanks!
Customer ID
Property ID
Bookings per customer
Cancellations per customer
A
1
0
1
B
2
10
1
C
3 , 4
100
1
D
5
20
1
We can try:
SELECT
customer_id,
ARRAY_JOIN(ARRAY_AGG(property_id), ',') AS properties,
bookings_per_customer,
cancellations_per_customer
FROM yourTable
GROUP BY
customer_id,
bookings_per_customer,
cancellations_per_customer;

sql select rows with exact filters

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

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.

Sum of Distinct count in Oracle

I have the following table:
CUST_PRODUCT_DTL
Cust_ID Product_ID QTY
1 10 5
2 10 2
3 10 5
1 11 5
2 12 1
How can I get Total Distinct CUST_ID, TOTAL DISTINCT PRODUCT_ID from the above table in Oracle 11 G
The below one doesn't work
SELECT SUM(COUNT(DISTINCT cust_id)), product_id
FROM CUST_PRODUCT_DTL
WHERE
GROUP BY product_id , cust_id
The desired result I am looking at is
Total Unique Cust_id: 3
Total Unique Product_id:3
sum is not involved, nor do you need the group by. Your desired output contains only one row. You just want two count distincts:
select count(distinct cust_id) as total_distinct_cust_id,
count(distinct product_id) as total_distinct_prod_id
from cust_product_dtl

SQL Selecting rows with multiple values

I have these 2 tables:
Table SW_ITEM:
ID SWID ITEM_ID
1 1 99
2 2 99
3 5 99
4 2 100
5 1 100
6 1 101
7 2 102
Table ITEM:
ID FILENAME
99 abc
100 def
101 geh
102 ijk
column ITEM_ID is a foreign key to the column ID of table ITEM.
So I want all filenames which have the SWID "1" AND "2" (that would be ITEMID 99 and 100, so their filenames are "abc" and "def")
Here I have to say that it is possible that ITEM_ID has more than one entry with the same SWID, so I cannot use this SQL:
SELECT ITEM_ID FROM SW_ITEM
WHERE SWID IN (1,2)
GROUP BY ITEM_ID
HAVING COUNT(ITEM_ID) = 2
So is there any other possibility to get all entries which have the SWID 1 and 2 (creating a join for every SWID is also not an option - because with many entries it would be really slow)
Kind regards
You need to use DISTINCT in COUNT and count SWID instead of ITEM_ID:
SELECT ITEM_ID FROM SW_ITEM
WHERE SWID IN (1,2)
GROUP BY ITEM_ID
HAVING COUNT(DISTINCT SWID) = 2;
Please checkout this demo.
To retrieve all filenames, try:
SELECT ITEM_ID, FILENAME
FROM ITEM JOIN SW_ITEM ON ITEM.ID = SW_ITEM.ITEM_ID
WHERE SWID IN (1,2)
GROUP BY ITEM_ID
HAVING COUNT(DISTINCT SWID) = 2;
Demo
I have a little different problem where I have to find a person with multiple entries in the same table based on email for that the above solution didn't work for me. You can try using the following,
SELECT person_id,
(ROW_NUMBER () OVER (PARTITION BY pers_email ORDER BY pers_name) person_count
from pers_table
WHERE person_count > 2;
Try this hope it works :)