Retrieving a list of rows with only a single item from other table in Oracle - oracle

I have two tables in Oracle database (10g express)
product
product_image
One product can have multiple images. Hence, there a one-to-many relationship from product to product_image and the product_image table has a foreign key that refers to the primary key of the product table.
I need to fetch a list of products with only a single image name in each row of the result set being retrieved regardless of the images being in the product_image table (even though there are no images for some of products).
The image name to be retrieved from the product_image table is generally the first image name in the product_image table after sorting each set of images for each product in ascending order. Something like the following.
prod_id prod_name prod_image
1 aaa aaa.jpg //The first image name in the product_image table after sorting images for prod_id in ascending order.
2 bbb bbb.jpg //Similar to the first case.
3 ccc - //No image(s) found in the product_image table
4 ddd - //Similar to the previous case.
The general join statement for these two tables would be something similar to the following.
SELECT p.prod_id, p.prod_name, pi.prod_image
FROM product p
INNER JOIN product_image pi
ON p.prod_id=pi.prod_id;
Is this possible using a single SQL statement?

If I understood your question correctly I think the following query will work. I have not tested it.
SELECT p.prod_id, p.prod_name, MIN(DBMS_LOB.substr(pi.prod_image, 1))
FROM product p LEFT JOIN product_image pi
ON p.prod_id=pi.prod_id
GROUP BY p.prod_id, p.prod_name
ORDER BY p.prod_name;

Try this, you can generate row number for each image per prod_id and use that. To return null or blank from missing product image you should use left outer join
WITH CTE AS
(
SELECT prod_id, DBMS_LOB.substr(prod_image,1,4000) prod_image,
row_number() over (partition by prod_id order by prod_image) rn
FROM product_image
)
SELECT p.prod_id, p.prod_name, nvl(pi.prod_image,'-') prod_image
FROM product p
LEFT OUTER JOIN CTE pi
ON p.prod_id=pi.prod_id and pi.rn = 1;

The following SQL worked as mentioned in the question.
SELECT
p.prod_id,
p.prod_name,
t.prod_image
FROM
product p
LEFT OUTER JOIN(
SELECT
pi.prod_image_id,
pi.prod_id,
pi.prod_image
FROM
product_image pi
INNER JOIN (
SELECT
MIN(pi.prod_image_id) AS prod_image_id
FROM
product_image pi
GROUP BY
pi.prod_id
) prod_image
ON pi.prod_image_id=prod_image.prod_image_id
)t ON p.prod_id=t.prod_id ORDER BY p.prod_id DESC;
Reference:
SQL Select only rows with Max Value on a Column

Related

oracle select query based on other table row level condition

I want to find the orders number from table#orders where DelivaryDateRevision less than max revisions from each country(table#maxrevisions). Countrycode is not the foreign key to the other table.
Can I fetch the orders table records if the country code is missing in the maxrevisions table.
Table: orders
OrderNumber | CountryCode | DelivaryDateRevision
123--------------- IN-------------------9
234--------------- US-------------------3
238-------------- IN------------------ 3
table: maxrevisions
CountryCode| MaxRevision
IN ---------------6
US--------------- 4
My query:
SELECT distinct o.ordernumber,o.countrycode
FROM orders o
left outer join maxrevisions m
on o.CountryCode=m.CountryCode
and
o.DelivaryDateRevision<rs.MaxRevision;
but I am getting the wrong result. Can I get any help here?
Your major omission seems to be a WHERE clause which compares the two revisions:
SELECT
o.ordernumber,
o.countrycode
FROM orders o
LEFT JOIN maxrevisions m
ON o.CountryCode = m.CountryCode
WHERE
o.DelivaryDateRevision < m.MaxRevision OR m.MaxRevision IS NULL;
Demo
Select
ordernumber,
countrycode,
deliverydateversion
from orders o
where deliverydateversion >
(
select max(revision)
from maxrevisiontab
where countrycode= o.countrycode
)
Please change the table names and column names as per your structure.

Oracle how to use distinct command in join

Im am trying to get a list of distinct values from one column whilst getting the key column data by inner join on another table as below..table a and table b hold key column of client.
Table b holds column product which has a range of values against a range of client numbers
Table a holds only client numbet
Table b holds client number and product
Client product
1. A
1. B
2. B
3. C
I want to find the list of distinct product values where the client is in table a and table b
Any suggestions welcome
find the list of distinct product values where the client is in table
a and table b
As you will notice below "distinct" isn't applied in joins
SELECT DISTINCT
b.Product
FROM TABLEA a
INNER JOIN TABLEB b ON a.Client = b.Client
;
The inner join ensures that client exists in both A and B and then the "select distinct" removes any repetition in the list of products.
SELECT
b.Product
, COUNT(*) AS countof
FROM TABLEA a
INNER JOIN TABLEB b ON a.Client = b.Client
GROUP BY
b.Product
;
An alternative, which also makes a distinct list of products where clients are in A and B is to use group by, with the added bonus that this way you can do some extra stuff like counting how often a product is referenced.
try it at SQLFiddle.com

Rebuild oracle hierarchical query from two tables

I am working on oracle hierarchical query for the below table
Classification_Product and Order_details tables
Classification Product has the Classification_id which will be stored in the Order_detailsaccording to user selection
Classification Product table
Order_details table
I want to select all products from Order_details table that has a parent LED Screen which will return all product that has parent LED Screen no matter what the child is 32inch or 50 inch or sony samsung etc etc
I tried to use below query but its replate rows a lot
SELECT B.CLASSIFICATION_ID, LEVEL AS VLEVEL, A.CATEGORY_ID, A.CATEGORY_DESC, CONNECT_BY_ISLEAF AS leaf
FROM PRODUCT_CLASSIFICATION A, ORDER_DETAILS B
WHERE A.STATUS = 1 and b.created_on like sysdate--AND leaf =1
START WITH A.CATEGORY_ID IS NULL
CONNECT BY A.CATEGORY_ID = PRIOR A.CLASSIFICATION_ID
ORDER SIBLINGS BY A.CLASSIFICATION_ID;
select od.*
from order_details od
where
od.classification_id in (
select p.classification_id
from product p
start with p.category_desc = 'LED Screen'
connect by prior p.classification_id = p.category_id
)

Oracle 11g - Selecting multiple records from a table column

I was just wondering how you select multiple records from a table column. Please see below the query.
SELECT DISTINCT DEPARTMENT_NAME, CITY, COUNTRY_NAME
FROM OEHR_DEPARTMENTS
NATURAL JOIN OEHR_EMPLOYEES
NATURAL JOIN OEHR_LOCATIONS
NATURAL JOIN OEHR_COUNTRIES
WHERE JOB_ID = 'SA_MAN' AND JOB_ID = 'SA_REP'
;
Basically, I want to be able to select records from the table column I have, however when you use AND it only displays SA_MAN and not SA_REP. I have also tried to use OR and it displays no rows selected. How would I actually be able to select both Job ID's without it just displaying one or the other.
Sorry this may sound like a stupid question (and probably not worded right), but I am pretty new to Oracle 11g SQL.
For your own comfort while debugging, I suggest you to use inner joins instead of natual joins.
That where clause is confusing, if not utterly wrong, because you don't make clear which tables' JOB_ID should be filtered. Use inner joins, give aliases to tables, and refer to those aliases in the where clause.
select distinct DEPARTMENT_NAME, CITY, COUNTRY_NAME
from OEHR_DEPARTMENTS t1
join OEHR_EMPLOYEES t2
on ...
join OEHR_LOCATIONS t3
on ...
join OEHR_COUNTRIES t4
on ...
where tn.JOB_ID = 'SA_MAN' AND tm.JOB_ID = 'SA_REP'
After rephrasing your query somehow like this, you'll have a clearer view on the logical operator you'll have to use in the where clause, which I bet will be an OR.
EDIT (after more details were given)
To list the departments that employ staff with both 'SA_MAN' and 'SA_REP' job_id, you have to join the departments table with the employees twice, once with the filter job_id='SA_MAN' and once with job_id='SA_REP'
select distinct DEPARTMENT_NAME, CITY, COUNTRY_NAME
from OEHR_DEPARTMENTS t1
join OEHR_EMPLOYEES t2
on t1.department_id = t2.department_id --guessing column names
join OEHR_EMPLOYEES t3
on t1.department_id = t3.department_id --guessing column names
join OEHR_LOCATIONS t4
on t1.location_id = t4.location_id --guessing column names
join OEHR_COUNTRIES t5
on t4.country_id = t5.country_id --guessing column names
where t2.job_id = 'SA_MAN' and t3.job_id = 'SA_REP'
order by 1, 2, 3

checking values from two tables?

I had two tables
table1 contains a list of customer and their info and there is a customer id for each one
table2 contains a list of request from all with and customer id for each request as foreign key
and i want to check the customer who has request and who is not
plz how should that be done logical is it possible to eqaul between two queries ?
thanks
You have two tables, the first with one row per customer, the other with zero to many rows per customer. So you need two techniques: one to reduce the second table to one row per customer and the other to join that result set to the first table. These techniques are an aggregating sub-query and an outer join respectively.
select c.customer_id
, nvl(r.req_count, 0) as no_of_reqs
from customer c
left outer join ( select customer_id
, count(*) as req_count
from customer_req
group by customer_id ) r
on c.customer_id = r.customer_id

Resources