SQL proble with join condition - sql

I have a data base like here
I need to create a request to list the number of product available by product category.
However i should not list the product category without products.
We want at the end only column CATEGORY_NAME (product_category.name) and PRODUCT_COUNT
Example of result :
---------------------------------
| CATEGORY_NAME | PRODUCT_COUNT |
---------------------------------
| Books | 3 |
| Automotive | 2 |
| High-tech | 8 |
--------------------------------
I try this request but it's not good:
SELECT name AS CATEGORY_NAME, COUNT(available_stock) AS PRODUCT_COUNT
FROM product
GROUP BY name
WHERE available_stock IS NOT NULL

Related

How can I query this as I want?

I have three table like this:
Product
| ID | Name |
+----------------+
| 1 | Product A |
| 2 | Product B |
ProductDescription
| ID | Description |
+------------------------------------+
| 1 | Product A English Description |
| 2 | Product A Spanish Description |
| 3 | Product B English Description |
| 4 | Product B Spanish Description |
And finally a table to connect 2 above table
ProductProductDescription
| ProductID | ProductDescriptionID |
+----------------------------------+
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 2 | 4 |
When I joined 3 above table normally, I got this
| ProductID | ProductDescripton |
+-------------------------------------------+
| 1 | Product A English Description |
| 1 | Product A Spanish Description |
| 2 | Product B English Description |
| 2 | Product B Spanish Description |
But I want to query into this:
| ProductID | English Description | Spanish Description |
+---------------------------------------------------------------------------+
| 1 | Product A English Description| Product A Spanish Description |
| 2 | Product B English Description| Product B Spanish Description |
Can you help me?
I think you want conditional aggregation:
select ppd.id,
max(case when pd.description like '%English%' then pd.description end) english_description,
max(case when pd.description like '%Spanish%' then pd.description end) spanish_description
from ProductProductDescription ppd
inner join ProductDescription pd on pd.id = ppd.productdescriptionid
group by ppd.id
Notes:
design-wise, it would be far better to have another column in product description table that represents the language of the description, rather than relying on the description itself
you don't need the product table to generate the expected result; but if you do, then just add another join to the query
One option would be using PIVOT Clause (if available for your DBMS) as
SELECT *
FROM
(
SELECT ppd.ProductID, pd.Description, LTRIM(REPLACE(pd.Description,p.Name)) AS Title
FROM ProductDescription pd
JOIN ProductProductDescription ppd
ON ppd.ProductDescriptionID = pd.ID
JOIN Product p
ON ppd.ProductID = p.ID
)
PIVOT
(
MAX(Description) FOR Title IN ('English Description' AS " English Description",
'Spanish Description' AS " Spanish Description")
)
Demo

Select based on multiple ID's in the same column

I have two SQL tables already built (not by me) :
One table that has all the ingredients with ID's assigned to them :
IngredientID | IngredientName
1 | Milk
2 | Eggs
3 | Flower
and the second table that has finished products that have reference to ingredientID in the ProductIngredients column but no the product name and they are built like this :
ProductID | ProductName | ProductIngredients
1 | Tomato Soup | NULL
2 | Pancakes | ;1;2;3
3 | Omlette | ;1;2
If they don't have any reference then its written NULL, and if they have, then they start with a ";" symbol and every ingredient is divided by a ";" symbol.
My goal is to join those two tables and make a select statement that returns me, instead of the ID's of the other column, the actual names of the used ingredients like this :
ProductID | ProductName | ProductIngredients
1 | Tomato Soup |
2 | Pancakes | Milk, Eggs, Flower
3 | Omlette | Milk, Eggs
Can anyone help out with this?
You need a left join of Products to ProductIngredients and group by product:
select p.ProductID, p.ProductName,
group_concat(i.IngredientName order by i.IngredientID) ProductIngredients
from Products p left join Ingredients i
on concat(p.ProductIngredients, ';') like concat('%;', i.IngredientID,';%')
group by p.ProductID, p.ProductName
The function group_concat() works in MySql but you can find similar functions to other databases.
See the demo.
Results:
| ProductID | ProductName | ProductIngredients |
| --------- | ----------- | ------------------ |
| 1 | Tomato Soup | |
| 2 | Pancakes | Milk,Eggs,Flower |
| 3 | Omlette | Milk,Eggs |

Return rows from a table and add field for that row if the ID has a relationship with another table

DBMS used: Amazon Aurora
I have a table that I store a list of all my products, let's call it products
+----+--------------+
| id | product_name |
+----+--------------+
| 1 | Product 1 |
+----+--------------+
| 2 | Product 2 |
+----+--------------+
| | |
+----+--------------+
Another table called redeemed_products stores the ID of the product that the user has redeemed.
+----+---------+------------+
| id | user_id | product_id |
+----+---------+------------+
| 1 | 1 | 1 |
+----+---------+------------+
| | | |
+----+---------+------------+
| | | |
+----+---------+------------+
I would like to retrieve all rows of products and add an extra field to the row which has a relation in the redeemed_products
+----+--------------+----------+
| id | product_name | redeemed |
+----+--------------+----------+
| 1 | Product 1 | true |
+----+--------------+----------+
| 2 | Product 2 | |
+----+--------------+----------+
| | | |
+----+--------------+----------+
The purpose of this is to retrieve the list of products and it will show which of the product has already been redeemed by the user. I do not know how I should approach this problem.
Use an outer join:
select p.id, p.product_name, rp.product_id is not null as redeemed
from products p
left join redeemed_products rp on rp.product_id = p.id;
Note that this will repeat rows from the products table if the product_id occurs more than once in the redeemed_products table (e.g. the same product_id for multiple user_ids).
If that is the case you could use a scalar sub-select:
select p.id, p.product_name,
exists (select *
redeemed_products rp
where rp.product_id = p.id) as redeemed
from products p;
You haven't tagged your DBMS, but the above is standard ANSI SQL, but not all DBMS products actually support boolean expressions like that in the SELECT list.
One option would be using a conditional within a LEFT JOIN query :
SELECT p.*, CASE WHEN r.product_id IS NOT NULL THEN 'true' END AS redeemed
FROM products p
LEFT JOIN redeemed_products r
ON r.product_id = p.id

Query to fetch non distinct records from a table

Need to know SQL query to fetch data as following
TableA
------------------------------------
| CUSTOMER_ID | ACCOUNT_TYPE |
_____________________________________
| 1 | SB |
| 1 | SB |
| 2 | SB |
| 2 | CR |
| 3 | CR |
_____________________________________
There is a requirement to fetch rows as follows
------------------------------------
| CUSTOMER_ID | ACCOUNT_TYPE |
_____________________________________
| 1 | SB |
| 1 | SB |
| 3 | CR |
_____________________________________
I need to eliminate the customer_id details which has two different account_type and show only customer_id to which the ACCOUNT type is either same are has only one row.
Can someone help in giving a ORACLE SQL query for this.
Thanks in advance
I only focused on the following requirements you provided.
I need to eliminate the customer_id details which has two different
account_type and show only customer_id to which the ACCOUNT type is
either same are has only one row.
You need to eliminate customer_id details which has two different account_type
SELECT CUSTOMER_ID, ACCOUNT_TYPE
FROM CUSTOMER
WHERE COUNT(ACCOUNT_TYPE) > 1 AND COUNT(CUSTOMER_ID) > 1
ORDER BY CUSTOMER_ID, ACCOUNT_TYPE;
I don't understand your requirements, it is ambiguous. Please revise your statement.

Find supplier which supplies a product that others don't

I'm trying to write an SQL query which selects the supplier based on the fact that it can supply a product other suppliers cannot.
I have 2 columns:
Supplier and Product
How would I select all the suppliers which supply at least 1 product which other suppliers do not supply?
I currently have:
SELECT incart.product, incart.supplier
FROM incart
WHERE incart.product
HAVING count(incart.supplier)=1
;
Try this:
SELECT
i1.supplier
FROM incart i1
WHERE i1.product NOT IN(SELECT product
FROM incart i2
WHERE i1.supplier <> i2.supplier);
For example, for the following sample data:
| PRODUCT | SUPPLIER |
|---------|----------|
| 1 | a |
| 2 | b |
| 3 | b |
| 2 | c |
| 3 | c |
| 4 | c |
It will select suppliers a and c, because supplier a supplies product 1 which others don't, and supplier c supplies product 4 which others don't.
SQL Fiddle Demo