checking values from two tables? - oracle

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

Related

Oracle select rows from a query which are not exist in another query

Let me explain the question.
I have two tables, which have 3 columns with same data tpyes. The 3 columns create a key/ID if you like, but the name of the columns are different in the tables.
Now I am creating queries with these 3 columns for both tables. I've managed to independently get these results
For example:
SELECT ID, FirstColumn, sum(SecondColumn)
FROM (SELECT ABC||DEF||GHI AS ID, FirstTable.*
FROM FirstTable
WHERE ThirdColumn = *1st condition*)
GROUP BY ID, FirstColumn
;
SELECT ID, SomeColumn, sum(AnotherColumn)
FROM (SELECT JKM||OPQ||RST AS ID, SecondTable.*
FROM SecondTable
WHERE AlsoSomeColumn = *2nd condition*)
GROUP BY ID, SomeColumn
;
So I make a very similar queries for two different tables. I know the results have a certain number of same rows with the ID attribute, the one I've just created in the queries. I need to check which rows in the result are not in the other query's result and vice versa.
Do I have to make temporary tables or views from the queries? Maybe join the two tables in a specific way and only run one query on them?
As a beginner I don't have any experience how to use results as an input for the next query. I'm interested what is the cleanest, most elegant way to do this.
No, you most probably don't need any "temporary" tables. WITH factoring clause would help.
Here's an example:
with
first_query as
(select id, first_column, ...
from (select ABC||DEF||GHI as id, ...)
),
second_query as
(select id, some_column, ...
from (select JKM||OPQ||RST as id, ...)
)
select id from first_query
minus
select id from second_query;
For another result you'd just switch the tables, e.g.
with ... <the same as above>
select id from second_query
minus
select id from first_query

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

Retrieving a list of rows with only a single item from other table in 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

select query with if in oracle

I need help! For example, there are four tables: cars, users, departments and join_user_department. Last table used for M: N relation between tables user and department because some users have limited access. I need to get the number of cars in departments where user have access. The table “cars” has a column department_id. If the table join_user_department doesn’t have any record by user_id this means that he have access to all departments and select query must be without any condition. I need do something like this:
declare
DEP_NUM number;--count of departments where user have access
CARS_COUNT number;--count of cars
BEGIN
SELECT COUNT (*) into DEP_NUM from join_user_departments where user_id=?;
SELECT COUNT(*) into CARS_COUNT FROM cars where
IF(num!=0)—it meant that user access is limited
THEN department_id IN (select dep_id from join_user_departments where user_id=?);
A user either has access to all cars (I'm assuming all cars are tied to a department, and the user has access to all departments) or the user has limited access. You can use a UNION ALL to bring these two groups together, and group by user to do a final count. I've cross joined the users with unlimited access to the cars table to associate them with all cars:
(UPDATED to also count the departments)
select user_id,
count(distinct department_id) as dept_count,
count(distinct car_id) as car_count,
from (
select ud.user_id, ud.department_id, c.car_id
from user_departments ud
join cars c on c.department_id = ud.department_id
UNION ALL
select u.user_id, v.department_id, v.car_id
from user u
cross join (
select d.department_id, c.car_id
from department d
join cars c on c.department_id = d.department_id
) v
where not exists (
select 1 from user_departments ud
where ud.user_id = u.user_id
)
)
group by user_id
A UNION ALL is more efficient that a UNION; a UNION looks for records that fall into both groups and throws out duplicates. Since each user falls into one bucket or another, UNION ALL should do the trick (doing a distinct count in the outer query also rules out duplicates).
"If the table join_user_department doesn’t have any record by user_id
this means that he have access to all departments"
This seems like very bad practice. Essentially you are using the absence of records to simulate the presence of records. Very messy. What happens if there is a User who has no access to a Car from any Department? Perhaps the current business logic doesn't allow this, but you have a "data model" which won't allow to implement such a scenario without changing your application's logic.

Resources