I have one table (table1) with columns:
ID
NAME
1
A
2
B
3
C
4
D
and another table (table2) with columns:
ID
table1.ID
DATE
STATUS
1
1
21-JUL-2020
INACTIVE
2
1
22-JUL-2022
ACTIVE
3
1
23-JUL-2022
ACTIVE
4
2
21-JAN-2022
ACTIVE
5
2
22-JAN-2022
INACTIVE
6
2
23-JAN-2022
ACTIVE
7
3
20-JAN-2022
INACTIVE
8
3
20-JAN-2022
INACTIVE
I am trying to write a query that will return distinct rows from table1 where status from table2 is ACTIVE and results should be ordered by min DATE from table2.
Desired result:
ID
NAME
2
B
1
A
I tried with the following:
select t1, min(t2.date)
from table1 t1 join t1.t2List t2 -- table1 Entity has OneToMany t2List defined
where t2.status = 'ACTIVE'
group by t1.id
order by t2.date desc;
Problem here is that I can't use my Entity class table1 and I would like to avoid creating a new class that will hold this additional aggregated result (min date).
Also tried using HAVING clause but could not get it working.
select t1 from table1 t1
where t1.id in (
select table1.id from table2 t2 where t2.status = 'ACTIVE'
group by t1.id, t2.date
having t2.date = min(t2.date));
Appriciete any help here!
Join table1 to a query that aggregates in table2 and returns all table1_ids with an ACTIVE row:
SELECT t1.*
FROM table1 t1
INNER JOIN (
SELECT table1_id, MIN(date) date
FROM table2
WHERE status = 'ACTIVE'
GROUP BY table1_id
) t2 ON t2.table1_id = t1.id
ORDER BY t2.date;
See the demo.
There are multiple ways of solving this problem, as #forpas has already answered
using a subquery in the JOIN clause.
The same results can be achieved using this query
SELECT table1.ID , table1.name
FROM table1
INNER JOIN table2 ON table2.table1_ID = table1.ID
WHERE status = 'ACTIVE'
GROUP BY table1.ID , table1.name
ORDER BY MIN(table2.statusDate)
Related
I am facing an issue in Oracle Query to achieve the following use case,
Consider I have two tables :
Table 1 : product
productId - Integer - primaryKey
productName - Varchar
Table 2 : product_sequence
productId - Integer - primaryKey
sequenceId - Integer - primaryKey
orderId - Integer
orderName - Varchar
product table has 1000 entries and product_sequence table has 10K entries
Requirement :
(paginate) fetch the entries from 0 to 100 / 100 to 200 / etc., in the product table
Distinct count of productId for showing the pagination in UI (check the sample query below)
Filter by 'productName' in 'product' table and 'orderName' in 'product_sequence' table
Query (tried) :
SELECT
p.productId, p.productName, ps.orderId, ps.orderName,
COUNT(distinct p.productId) OVER () AS TOTAL
FROM (
select *
from product
OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY
) p
JOIN product_sequence ps on p.productId=ps.productId
WHERE ps.orderId IN ('12','13','14');
NOTE : the above query will work in Oracle, But the issue is
Expected:
Return 100 entries from 'product' table with mapped entries in the 'product_sequence' table
Actual :
It first LIMITS 100 entries in product and then filter the orderId so the number of entries returned is reduced from 100 to lesser number
I agree my query is not correct: It first LIMIT by 100 in 'product' table in subquery and then goes for filter in second table which reduces the count
Could some one help me with the query for this please? Anyhelp is appreciated.
If my question is not clear, Let me know, I can explain with more info.
Try to move the OFFSET and FETCH clauses to the outer query, something like this:
SELECT q.productId, q.productName, q.orderId, q.orderName,
COUNT(distinct p.productId) OVER () AS TOTAL
FROM ( SELECT * FROM product p JOIN product_sequence ps ON p.productId = ps.productId
WHERE ps.orderId IN ('12','13','14') ) q
OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY
To get 100 rows per page "after filtering" you'll need to find all the productid values first, then process the main query.
For example:
select
p.productid, p.productname, ps.orderid, ps.orderName,
count(distinct p.productid) over() as total
from product p
join product_sequence ps on p.productid = ps.productid
where ps.orderid in ('12','13','14')
and p.productid in (
select *
from (
select distinct p.productid
from product p
join product_sequence ps on p.productid = ps.productid
where p.productname like '%theremin%' -- filter #1
and ps.orderid in ('12','13','14') -- filter #2
) x
order by productid
offset 300 rows -- get the 4th page
fetch first 100 rows only -- page size set to 100 rows
)
See example at db<>fiddle.
I have a problem about sql performance, my db is too many rows, so this make long time to query.
SELECT * FROM A JOIN B ON A.id = B.id where ...
So I change to
SELECT * FROM A where A= a...
SELECT * FROM B where B= b...
I got 2 resultSet from 2 query here.
Can someone help me how to join 2 resultset with the best performance.
I have to split to 2 query because this database have 10 mil records.
Select col1, col2 ...
from
(
-- first query
) as tab1
join
(
-- second query
) as tab2 on tab1.colx = tab2.coly
I got these two tables and I want to have a query to count the amount of cars by each brand and insert this count to a column in the brand table
I've tried many queries but can't get it right.
First table,
Second table,
Use JOIN.
Query
select t1.car_brand_id, t2.brand_name, count(t1.car_name) as total_count
from table1 t1
join table2 t2
on t1.car_brand_id = t2.brand_id
group by t1.car_brand_id, t2.brand_name;
You need join count and group by
this is a select for see the count by brand_name
select b.brand_name, count(*)
from table_one a
inner join table_two b on b.brand_id = a.brand_id
group by b.brand_name
Once you have added the column you need in table_two ( with eg alter table command adding my_count_col)
you could use an update like this
update table_two
inner join (
select b.brand_name, count(*) my_count
from table_one a
inner join table_two b on b.brand_id = a.brand_id
group by b.brand_name ) t on t.brand_name = table_two.brand_name
set table_two.my_count_col = t.my_count
I have four columns, 2 columns lets say FIRST_NAME and LAST_NAME in table PersonalInfo and other 2 columns ADD1 and ADD2 in table AddressDetails. Now what I have to do is I want to know the count for duplicate record for each row considering all 4 columns.How can I do that?
I have 2 approach till now:
1. I iterate each response and compare with the remaining.
2. Do something with query.
I know the first case is worst option because it will take so much of the time. Is there something I can do with query?
I searched and found this:
SELECT LAST_NAME, count(LAST_NAME) FROM SchemaName.PersonalInfo S GROUP by LAST_NAME;
and the basic is working for single column and not for multiple columns.
How can I do it. Please suggest.
Group by all the cols not just last name.
Working fiddle : http://sqlfiddle.com/#!9/a76e7e/3
SELECT P.fname,P.lname,A.add1,A.add2, count(*)
FROM PersonalInfo P, AddressDetails A
Where P.id = A.id
GROUP by P.fname,P.lname,A.add1,A.add2
having count(*) > 1;
Join you tables on the id like in above example.
I suppose you table PersonalInfo has a primary key and AddressDetails ha a forey key on this primary key ?
select t1.FIRST_NAME , t1.LAST_NAME, t2.ADD1 , t2.ADD2, count(*) NbPossibility
from PersonalInfo t1 inner join AddressDetails t2
on t1.idPersonalInfo=t2.idPersonalInfo
group by t1.FIRST_NAME , t1.LAST_NAME, t2.ADD1 , t2.ADD2
having count(*)>1
Il you have not keys for join this tables (anormal):
select t1.FIRST_NAME , t1.LAST_NAME, t2.ADD1 , t2.ADD2, count(*) NbPossibility
from PersonalInfo t1 cross join AddressDetails t2
group by t1.FIRST_NAME , t1.LAST_NAME, t2.ADD1 , t2.ADD2
having count(*)>1
table1
id type name parent group_id
1 special name1 0 21
2 Group name2 1 19
3 Group name3 1 22
4 special name4 0 89
table2
id version mcs user right_id
1 0 15 27 3
2 0 15 27 4
And right_id in table2 references on id in table1.
What i want is to delete the rows in table1 where name = name2 and name3.
How to make this?
Use below mentioned query to delete required data from both tables
delete * from table1 as a join table2 as b on a.id=b.right_id where
a.name in ('name2','name3')
In addition to above answers, if you want that on deletion of any row in the parent table table1 , automatically a row in the table2 having value of right_id same as value of id in table1 should be deleted then you need to use ON DELETE CASCADE clause in the create script of your table2.
See this http://www.techonthenet.com/oracle/foreign_keys/foreign_delete.php
You can use below query which will delete records from both the tables:
DELETE a,b FROM table2 AS a
INNER JOIN table1 AS b ON a.right_id = b.id
WHERE b.name IN ('name1', 'name2');
DELETE FROM table1 AS A
INNER JOIN table2 AS B ON A.ID = B.RIGHT_ID
WHERE A.NAME IN (name1, name2)