'Oracle SQL - query from one table with two conditions
I need to select data from a table by two conditions
I have four tables
Tran
| tranid | payed |
|---|---|
| 123 | yes |
| 456 | yes |
| 789 | no |
Info
| tranid | contractname | amount | currency | accountid |
|---|---|---|---|---|
| 123 | finance | 10 | EUR | 12345 |
| 123 | card | 8 | USD | 54321 |
| 456 | finance | 20 | EUR | 67890 |
| 456 | card | 16 | USD | 09876 |
| 789 | finance | 30 | EUR | 13579 |
| 789 | card | 24 | USD | 97531 |
Account
| accountid | currencyid |
|---|---|
| 12345 | 124 |
| 54321 | 978 |
| 67890 | 124 |
| 09876 | 840 |
| 13579 | 124 |
| 97531 | 826 |
Currency
| currencyid | currencyname |
|---|---|
| 978 | EUR |
| 840 | USD |
| 826 | GBP |
| 124 | CAD |
I need to extract: tran id where payed = yes, amount where contract name = finance and account currency name where contact name = card
I have tried to make join with multiple select, but I always have error: ORA-01427: single-row subquery returns more than one row
select t.tranid,
(select i.amount
from tranid t
inner join info i on t.tranid = i.tranid
and t.payed = 'yes'
and i.contractname = 'finance') as "Amount",
c.currencyname as "Account currency"
from tran t
inner join info i on t.tranid = i.tranid
inner join account a on i.accountid = a.accountid
inner join currency c on a.currencyid= c.currencyid
and t.payed = 'yes'
and i.contractname = 'card'
Result must be:
| tranid | Amount | Account currency |
|---|---|---|
| 123 | 10 | EUR |
| 456 | 20 | USD |
Solution 1:[1]
The issue here is that your subquery is not correlated with your main query - it doesn't reference any of the outer query tables. If you run it by itself, you'll notice that it returns 2 rows.
select i.amount
from tranid t
inner join info i on t.tranid = i.tranid
and t.payed = 'yes'
and i.contractname = 'finance'
Also, when you reference the same table multiple times in a query, it's good practice to use different aliases for each one, so you can tell them apart.
Here's a relatively small change that should make your query work:
select t.tranid,
(select i2.amount
from info i2
where i2.tranid = i.tranid
and i2.contractname = 'finance') as "Amount",
c.currencyname as "Account currency"
from tran t
inner join info i on t.tranid = i.tranid
inner join account a on i.accountid = a.accountid
inner join currency c on a.currencyid= c.currencyid
and t.payed = 'yes'
and i.contractname = 'card'
Although if it were me, I wouldn't use a subquery at all - I'd just join the info table twice.
select t.tranid,
i2.amount as "Amount",
c.currencyname as "Account currency"
from tran t
inner join info i on t.tranid = i.tranid
and i.contractname = 'card'
inner join info i2 on t.tranid = i2.tranid
and i2.contractname = 'finance'
inner join account a on i.accountid = a.accountid
inner join currency c on a.currencyid= c.currencyid
and t.payed = 'yes'
I don't really understand your currency column in the info table, it doesn't seem to match up with the currency table. But I guess it's not relevant to the question.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | kfinity |
