Combine different table with same column without ambigous - sql

I have query problem. I have 3 table.
table A
----------------------------
NAME | CODE
----------------------------
bob | PL
david | AA
susan | PL
joe | AB
table B
----------------------------
CODE | DESCRIPTION
----------------------------
PL | code 1
PB | code 2
PC | code 3
table C
----------------------------
CODE | DESCRIPTION
----------------------------
AA | code 4
AB | code 5
AC | code 6
Table B and C have unique row.
the result I need :
----------------------------
NAME | CODE | DESCRIPTION
----------------------------
bob | PL | code 1
david | AA | code 4
susan | PL | code 1
joe | AB | code 5
What I have tried so far
http://sqlfiddle.com/#!9/ffb2eb/9

You are close. I think you just need COALESCE():
select A.*, coalesce(B.DESCRIPTION, C.DESCRIPTION) as description
from A left join
B
on A.CODE = B.CODE left join
C
on A.CODE = C.CODE
order by A.NAME;

I think UNION will make this. And additionally It will also remove duplicates if some will exists.
SELECT A.NAME , UN.CODE ,UN.DESCRIPTION
FROM A,
(SELECT CODE,DESCRIPTION FROM B
UNION
SELECT CODE,DESCRIPTION FROM C ) UN
WHERE A.CODE = UN.CODE;

Related

Get left table data completely even when there is no reference in right joined table

Database used: SQL Server
I have three tables A,B,C.
TABLE A:
------------------
| ID | Name |
------------------
| 1 | X |
------------------
| 2 | Y |
------------------
TABLE B:
----------------------
| ID | Date |
----------------------
| 1 | 2019-11-06 |
----------------------
| 2 | 2019-11-05 |
----------------------
TABLE C:
----------------------------------
| ID | B.ID | A.ID | Amount |
----------------------------------
| 1 | 1 | 1 | 500 |
----------------------------------
| 2 | 2 | 2 | 1000 |
----------------------------------
The result I would like to get is all entries of table A.Name with their amount in table C.amount where table B.Date = 2019-11-06. The result set should include all A.name entries even it have no reference in Table C.
Required result is:
-----------------------
| A.Name | C.Amount |
-----------------------
| X | 500 |
-----------------------
| Y | NULL |
-----------------------
Code I tried with :
SELECT A.Name,C.Amount
FROM A
LEFT OUTER JOIN C ON C.A_ID=A.ID
LEFT OUTER JOIN B ON B.ID = C.B_ID ON
WHERE B.Date='2019-11-06'
The result I obtained with above code is :
------------------
| Name | Amount |
------------------
| X | 500 |
------------------
There is no Y in the result, its because there is no entry for Y on that particular date. I just want to show Y and amount as null or zero.
SQL Fiddle with my query
Please help me with this.
There's is no relationship between your A and B, so we need to group B and C using a subquery to filter with date before doing the left join.
SELECT A.Name, t1.Amount
FROM A
LEFT JOIN
(SELECT C.A_ID, C.Amount FROM C
INNER JOIN B ON B.ID = C.B_ID
WHERE B.Date='2019-11-06') t1
ON t1.A_ID=A.ID
see dbfiddle
Try this-
Fiddle Here
SELECT A.Name,C.Amount
FROM A
LEFT JOIN B ON A.ID = B.ID AND B.Date = '2019-11-06'
LEFT JOIN C ON B.ID = C.ID
Output is-
Name Amount
X 500
Y (null)

Flag row has duplicate value

I have query problem. I have 3 table.
table A
----------------------------
NAME | CODE
----------------------------
bob | PL
david | AA
susan | PL
joe | AB
alfred | PL
table B
----------------------------
CODE | DESCRIPTION
----------------------------
PL | code 1
PB | code 2
PC | code 3
table C
----------------------------
CODE | DESCRIPTION
----------------------------
AA | code 4
AB | code 5
AC | code 6
Table B and C have unique row.
the result I need to flag which row has duplicate records:
-------------------------------------
NAME | CODE | DESCRIPTION | DUPLICATE
-------------------------------------
bob | PL | code 1 | YES
david | AA | code 4 | NO
susan | PL | code 1 | YES
joe | AB | code 5 | NO
Alfred | PL | code 1 | YES
What I have tried so far
http://sqlfiddle.com/#!9/ffb2eb/16
I don't see why you need tables B and C at all to calculate the flag. You can do this with window functions:
select a.*,
(case when count(*) over (partition by a.code) > 1 then 'YES' else 'NO'
end) as flag
from a;
You do need B and C if you want to bring in the additional values:
select a.*, coalesce(b.description, c.description) as description,
(case when count(*) over (partition by a.code) > 1 then 'YES' else 'NO'
end) as flag
from a left join
b
on a.code = b.code left join
c
on a.code = c.code;
Here is a working Oracle SQL Fiddle.
Try the below code in MYSQL (http://sqlfiddle.com/#!9/9a149b/1)
Note :- The code works in Oracle as well http://sqlfiddle.com/#!4/6c6df/5
select A.*,
COALESCE(B.DESCRIPTION, C.DESCRIPTION) AS DESCRIPTION,
dup.DUPLICATE
from A
left join B on A.CODE = B.CODE
left join C on A.CODE = C.CODE
INNER JOIN (select a.code,
case when count(a.code) > 1 then 'YES' else 'NO' end as
DUPLICATE
from A
group by a.code) dup
ON A.code=dup.code

Get values from 2 different table but shows only 1 table data

Hie
It might be unclear my query in the title,Let me clear you in the description.
I have 2 tables in the DB with name of 'ABC' and 'XYZ'.
ABC table
| ID | name | phone | gender |
1 | dave | 23423 | Male
2 | rayman | 987887 | female
3 | shawn | 6237267 | male
XYZ table
| ID | user-id | blood-group | rh-factor |
1 | 3 | AB | +
2 | 1 |
B | -
As you seen above there are two table, now I want result that user whose gender is Male, blood-group is B and rh-factor is negative.
but output should be
| ID | name | phone | gender |
1 | dave | 23423 | Male
hope you understand what I mean.I don't know there should be user GROUP BY or what.
thanks in advance.
SELECT a.* FROM ABC a JOIN XYZ b ON a.ID=b.ID
WHERE b.Bloodgroup='B' AND a.gender='Male' and b.rh_factor='-'
Try this!..
select abc.id,abc.name,abc.phone,abc.gender from abc inner join xyz
on abc.id = xyz.user-id where abc.gender = 'male' and xyz.blood-group = 'b' and xyz.rh-factor='-'
Regards.
SK
You can simply use INNER JOIN :
SELECT a.* FROM ABC a INNER JOIN XYZ b ON a.ID = b.`user-id`
WHERE b.bood_group = 'B' and b.rh-factor = '-'
Use backtick(`) if your column has hyphen in it like it in your user-id

SQL query with two columns as foreign keys of the same table

I have two tables
Table A
id ! name ! fk_1_table_B_1 ! fk_2_table_B_2
-------|------|----------------|--------------
1 | John | 1 | 3
2 | Paul | 2 | 1
3 | Anna | 4 | 2
4 | Alan ! 3 | 1
Table B
id | code
-------|------
1 | EN
2 | US
3 | FR
4 | IT
The idea is to obtain the following query
id ! name ! code (fk_1_table_B_1) ! code (fk_1_table_B_2)
-------!------!-----------------------!-----------------
1 | John | EN | FR
2 | Paul | US | EN
3 | Anna | IT | US
4 | Alan ! FR | EN
If Table A had only one FK Column from Table B I would do
SELECT tableA, name, tableB.code
FROM tableA, table B
WHERE tableA.fk_1_table_B_1 = tableB.id
How can I do this with Table A having two columns as FK from B? What should I select in the SELECT?EN
Thanks
You should join to the same table twice, giving it two different aliases:
SELECT a.id, a.name, b1.code, b2.code
FROM tableA a
JOIN tableB b1 ON b1.id = a.fk_1_table_B_1
JOIN tableB b2 ON b2.id = a.fk_2_table_B_2
Note how this query uses ANSI join syntax for better clarity: rather than listing all tables in the FROM clause, it puts each of the aliased tableBs in its own JOIN clause.
Maybe this?
select a.id, a.name,
(select b.code from B b where b.id = a.fk_1_table_B_1),
(select c.code from B c where c.id = a.fk_1_table_B_2),
from A a

Decode more than on ID with two tables

TABLE PEDIDO
id_name | ID_cabimento | ID_direction
1 | 4 | 5
2 | 3 | 6
3 | 4 | 5
TABLE USER
id_name | name
1 | João
2 | Maria
3 | António
4 | Manuel
I WANT FOR RESULT
name | cabimento | direction
João | Manuel | Tozé
Maria | António | Joaquim
António | Manuel | Tozé
...
I tried UNION and JOIN but did not get the desired result... because I only can decode 1 ID.
you can join n times on same table, just using n aliases
select n.name as name, c.name as cabimento, d.name as direction
from pedido p
inner join user n on p.id_name = n.id_name
inner join user c on p.id_name = c.id_cabimento
inner join user d on p.id_name = d.id_direction