I have three tables A,B and C.
A and B are connected a foreign key A.category_id=B.id ,
A and C have the same number of rows.
A
id category_id value1 value2
1 null 'A' null
2 null 'B' null
3 null 'C' null
4 null 'D' null
B
id category
1 0
2 1
C
id category
1 0
2 1
3 1
4 0
Expected result:
A
id value
1 1
2 2
3 2
4 1
I would like to receive updated A table where category_id will be id from table B based on table C category.
I have tried
UPDATE A SET
A.category_id = (
select B.id from A
left JOIN C
ON A.id = C.id
left join B on B.category=C.category
)
WHERE A.id IN (SELECT C FROM C WHERE A.id = C.id);
but then I received ORA-01427 single-row subquery returns more than one row tips
You are missing a correlation clause in the subquery:
update A
set category_id = (select B.id
from C join
B
on B.category = C.category
where A.id = C.id
)
where exists (select 1 from C where A.id = C.id);
To correlated a query, you refer to the outer reference typically in a where condition. You don't repeat the table reference in the from clause.
Note that an outer join is unnecessary. If there is no match, the value will be NULL.
Related
I have a sql table with records having types A ,B and C. There are some records with only type B and C . How can I find the records with only type B and C using sql query ?
Emp id type
1 A
1 B
1 C
2 B
2 C
3 A
3 C
4 A
4 B
so my query should return me employee id 2 as it doesn't have type A.
select empId
from your_table
group by empId
having sum(case when type not in ('B','C') then 1 else 0 end) = 0
You want to use a self join or a nested subselect:
select * from employees a
where type in ('B','C')
and not exists
(select 1 from employees b
where a.id = b.id
and b.type = 'A')
This will return all employee records that have types B or C, but not A.
i have following SQL table A in my database:
index, group, foo
1 A 2
2 A 2
3 A 0
4 A 1
5 B 2
6 B 1
7 C 1
There are few more groups and I need to write a query based on this filter table B. For each group in table A it's index should be equal or greater than index_egt from table B for the same group.
If the group is not listed in table B, the group won't be filtered.
index_egt, group
3 A
5 B
Expected result:
index, group, foo
3 A 0
4 A 1
5 B 2
6 B 1
7 C 1
Try this, the A.index>=B.index_egt will handle cases where the group is listed in TableB and the B.index_egt IS NULL will handle cases where the group is not listed:
SELECT
A.index,
A.group,
A.foo
FROM TableA AS A
LEFT JOIN TableB AS B ON A.group=B.group
WHERE A.index>=B.index_egt
OR B.index_egt IS NULL
select
a.*
from
A a
left join
B b ON b.group = a.group
where
a.index >= b.index_egt OR b.index_egt IS NULL
I always like this trick with coalesce
SELECT a.*
FROM a_table_with_no_name a
LEFT JOIN b_table_with_no_name b ON b.group = a.group
WHERE a.index >= COALESCE(b.index_egt,a.index)
I have 2 tables which I'd like to join and..
A:
ID Otherfields..
1 ...
2
3
4
B:
ID aId Otherfields..
1 1 ...
2 1
3 2
4 1
So I'm perfectly capable of joining them by a.Id but how do get I get the count for the matches in Table B, like:
a.id count(b)
1 3
2 1
I figured it must be something with count() over() but cannot recall the exact use.
Thanks!
You can simply do this:
SELECT
A.ID, COUNT(b.ID)
FROM A
INNER JOIN B ON A.Id = b.aID
GROUP BY A.ID
You can have
SELECT A.ID, COUNT(b.ID)
FROM A
LEFT JOIN B ON A.Id = b.aID
GROUP BY A.ID
This will give you all a.IDs that don't exist in b.ID and hence show their count as 0.
E.g.,
ID Count
1 3
2 1
3 0
4 0
I have two tables as given below
Table A Table B Table C
============= ============== =========
Id Name Id AId CId Id Name
1 A 1 1 1 1 x
2 B 2 1 1 2 y
3 C 3 2 1 3 z
4 D 4 2 3 4 w
5 E 5 3 2 5 v
Now I want all the records of Table A with matching Id column CId from Table B where CId = 1.
So the output should be like below :
Id Name CId
1 A 1
2 B 1
3 C 1
4 D Null
5 E Null
Can anyone help me please?
This does what you want:
SELECT
A.Id,
A.Name,
CASE B.CId WHEN 1 THEN 1 ELSE NULL END AS CId
FROM
A LEFT JOIN B ON A.Id = B.Id
This is not about LEFT JOINing. You could as well do it with an INNER JOIN. When you don't want the 3 and 2 of column CId to appear you would still have to filter with WHERE and therefore the rows with Id 4 and 5 would not appear, which is not what you want.
EDIT:
Given this test data:
create table A (Id int, Name varchar(5));
insert into A values
(1, 'A'),
(2, 'B'),
(3, 'C'),
(4, 'D'),
(5, 'E');
create table B (Id int, AId int, CId int);
insert into B values
(1,1,1),
(2,1,1),
(3,2,1),
(4,2,3),
(5,3,2);
my query does not give a cartesian product. Read and try before downvoting. Anyway, it was not clear to me what you want to achieve, now I've joined on AId column and with this query:
SELECT DISTINCT
A.Id,
A.Name
, CASE
WHEN B.CId > 1 THEN 1
WHEN B.CId = 1 THEN 1
ELSE NULL END AS CId
FROM
A LEFT JOIN B ON A.Id = B.AId
and it also gives the right output, like the first before. If this is still not what you want, your test data is wrong or I absolutely don't get it.
Try something like this:
SELECT TableA.Id, TableA.Name, TableB.CId
FROM TableA
LEFT OUTER JOIN TableB ON TableA.Id = TableB.CId
WHERE TableB.CId = 1
Hope this helps.
Edit:
The output you desired, can be achieved if you match TableA's ID column with TableB's ID column, NOT TableB's CId column. Try below which I tested in my pc and gives thee similar output you needed.
select TableA.Id, TableA.Name, TableB.CId
from TableA
left outer join TableB on TableA.Id = TableB.Id
and TableB.CId in
(
select TableB.CId
from TableB
left outer join TableC on TableB.CId = TableC.Id
WHERE TableB.CId = 1
)
group by TableA.Id, TableA.Name, TableB.CId
Please inform if I guess it right. Check the column names.
i have 3 tables (A,B,C)
Table A -
ID Name
1 Sam
2 Manuel
3 Jane
Table B
ID Tab_A_ID Name
1 1 Meer
2 1 Kutti
3 2 Mikaro
Table C
ID Tab_B_ID Price
1 1 255.11
2 1 30.52
3 3 125.22
I need a query that shall pick up the top price for TableA-Name from TableC. So only 1 top price for 1 nae record.
e.g.-
Sam - 255.11
Manuel - 125.22
How can i get this?
To get the max price per entry in A:
SELECT a.Name,
MAX(c.price)
FROM a
INNER JOIN b
ON a.id = b.tab_a_id
INNER JOIN c
ON b.id = c.tab_b_id
GROUP BY a.id, a.name
To get the max price per entry A per entry B:
SELECT a.Name,
b.Name
MAX(c.price)
FROM a
INNER JOIN b
ON a.id = b.tab_a_id
INNER JOIN c
ON b.id = c.tab_b_id
GROUP BY a.id, b.id, a.name, b.name
Note that entries in A without corresponding entires in B or entries in B without corresponding entries in C will not appear in the result. Use LEFT JOIN if you want to include these in the result.