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)
Related
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)
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
I have a table with huge data. I am storing logging details of rest call, where sentTime and a combination of three fields let say (COL1, COL2, COL3) are unique.
I need to get the last call for each rest call.
For example, if API1, API2, and API3 are called 10 times each, I have around 30 rows in my table. I need the last calls of all 3 API's so I will get 3 rows, one for each API.
I am using following query:
SELECT tb.id
FROM Table1 (nolock) tb
INNER JOIN (
SELECT col1, col2, col3, MAX(sentTime) as lastSentTime
FROM Table1 (nolock) GROUP BY col1, col2, col3) a
ON a.col1 = tb.col1 AND
a.col2 = tb.col2 AND
a.col2 = tb.col2 AND
a.lastSentTime = tb.sentTime
But it doesn't work as expected.
For example:
id Name Sent_Time Temp_id Temp_id2
1 Delete 04/03/16 17:54 AB 2222701
2 Update 04/03/16 17:54 UD 6900001
3 Create 04/03/16 17:54 EL 2017301
4 Read 04/03/16 17:54 AB 2670001
5 Update 08/03/16 17:54 UD 1069501
6 Create 08/03/16 17:54 EL 3490801
Except there are millions of rows.
The combination of name, Temp_id and Temp_id2 is unique.
In java I have taken all the data and put it into a HashMap with key as name + Temp_id + Temp_id2. So that it is unique. Is it possible I can get the same data through a query?
You could try this. I guess each distinct REST call has its own values of col1, col2, and col3 and you want the most recent.
SELECT MAX(sentTime) mostrecent_sentTime,
col1, col2, col3
FROM Table1
GROUP BY col1, col2, col3
If you want all the columns in the row, then use window functions:
select t.*
from (select t.*,
row_number() over (partition by col1, col2, col3 order by sentTime desc) as seqnum
from t
) t
where seqnum = 1;
If your table has only four columns (or you only care about four columns), then aggregation as suggested by #OllieJones is perhaps more reasonable.
There are three tables as follows
Table 1 - Vehicle
Vehicle_Id PRIMARY KEY
Name
Serial_Number
Table 2 - Propertyname
Property_Id PRIMARY KEY
Name
Table 3 - Property
Property_Id (FOREIGN KEY) references Property_Id from Propertyname table
Value
Id (FOREIGN KEY) references Vehicle_Id from Vehicle table
Sample Data
Table 1 - Vehicle
Vehicle_Id Name Serial_Number
1000 WagonR Maruti-WagonR
1001 Estilo Maruti-Estilo
1002 Zen Maruti-Zen
Table 2 - Propertyname
Property_Id name
100 Mileage
101 FuelType
102 Country
Table 3 - Property
Property_Id Value Id
100 50 1000
101 Petrol 1000
102 India 1000
100 35 1001
101 Diesel 1002
From the three tables we can see that each vehicle has a set of properties which are kept as rows in the Property table. This is done so that in case we add more properties to a vehicle we add a row entry for the vehicle rather than adding a column which is not feasible.
Now I have a UI where in i can search for vehicles based on their
1) Name, Serial_Number - These are available as columns in the Vehicle table &
2) Mileage, FuelType, Country - These are the properties for the particular Vehicle
The user can enter any combination of values in 1) and 2) above to search through the list of vehicles.
Eg:- If the user enters Mileage as 50 and FuelType as Diesel, i should fetch results of vehicles which have Mileage as 50 AND FuelType as Diesel.
I tried the following SQL statement to do the same
select vh.Vehicle_Id, vh.name, pt.Property_Id, pn.name, pt.value
from property pt
inner join propertyname pn
on pt.Property_Id=pn.Property_Id
inner join vehicle vh
on vh.Vehicle_Id=pt.Id
and ((pn.Name='Mileage' AND pt.Value='50') AND (pn.Name='FuelType' AND pt.Value='Petrol'));
But i get zero results due to the AND condition on the single row result. But if i change the last AND condition to OR i get two results which match the criteria.
But I am trying to fetch Vehicles which matches both the properties matching.
I have tried using INTERSECT, inner join of two SQL statements etc. But couldnt get the result.
Could anyone suggest me the best way to search on two property name,value pairs which exist as rows and not columns to get the exact search results.
Your issue is the PropertyName can't be both 'Mileage' and 'FuelType' at the same time
You can find all the vehicles where the id is in the intersection of the two propertyNames like this
select Vehicle_Id, Vehicle.Name, Serial_Number, PropertyName.Name, Property.Value
from Vehicle
join Property on (Property.Id = Vehicle.Vehicle_Id)
join PropertyName on (PropertyName.Property_Id = Property.Property_Id)
where Vehicle_id in
(select Id
from PropertyName
Join Property on (PropertyName.Property_Id = Property.Property_Id)
where PropertyName.Name = 'Mileage' and Property.Value = '50'
intersect
select Id
from PropertyName
Join Property on (PropertyName.Property_Id = Property.Property_Id)
where PropertyName.Name='FuelType' AND Property.Value='Petrol'
)
Vehicle_Id Name Serial_Number Name Value
1000 WagonR Maruti-WagonR Mileage 50
1000 WagonR Maruti-WagonR FuelType Petrol
1000 WagonR Maruti-WagonR Country India
There are various ways of doing it
I would do something like this
select vh.Vehicle_Id, pt_m.value as [Mileage], pt_f.value as [FuelType]
from vehicle vh
inner join propertyname pn_m ON pn_m.Name='Mileage'
inner join propertyname pn_f ON pn_f.Name='FuelType'
inner join property pt_m on pt_m.Property_Id=pn_m.Property_Id AND pt_m.Id = vh.Vehicle_Id
inner join property pt_f on pt_f.Property_Id=pn_f.Property_Id AND pt_f.Id = vh.Vehicle_Id
You'll need two aliases for the property name table as you're joining to two properties and you'll similarly need two aliases for the property value
An advantage of this is that
It can be quickly adapted to deal with vehicles where one of the properties isn't actually populated
select vh.Vehicle_Id, pt_m.value as [Mileage], pt_f.value as [FuelType]
from vehicle vh
left join propertyname pn_m ON pn_m.Name='Mileage'
LEFT join propertyname pn_f ON pn_f.Name='FuelType'
LEFT join property pt_m on pt_m.Property_Id=pn_m.Property_Id AND pt_m.Id = vh.Vehicle_Id
LEFT join property pt_f on pt_f.Property_Id=pn_f.Property_Id AND pt_f.Id = vh.Vehicle_Id
Or even deal with inconsistend property names
select vh.Vehicle_Id, pt_m.value as [Mileage], pt_f.value as [FuelType]
from vehicle vh
left join propertyname pn_m ON pn_m.Name='Mileage'
LEFT join propertyname pn_f ON pn_f.Name IN ('FuelType','Fuel Type')
LEFT join property pt_m on pt_m.Property_Id=pn_m.Property_Id AND pt_m.Id = vh.Vehicle_Id
LEFT join property pt_f on pt_f.Property_Id=pn_f.Property_Id AND pt_f.Id = vh.Vehicle_Id