I have problem when joining tables (left join)
table1:
id1 amt1
1 100
2 200
3 300
table2:
id2 amt2
1 150
2 250
2 350
my Query:
select id1,amt1,id2,amt2 from table1
left join table2 on table2.id1=table1.id2
My supposed o/p is:
id1 amt1 id2 amt2
row1: 1 100 1 150
row2: 2 200 2 250
row3: 2 200 2 350
I want o/p in row3 as
2 null 2 350
ie I want avoid repetition of data(amt1).
This really is a formatting issue which is best handled by the client. For instance, in SQL*Plus we can use BREAK ....
SQL> select t1.*, t2.* from t1, t2
2 /
A B C D C1
--- --- --- --- ----------
aaa bbb ccc ddd 111
aaa bbb ccc ddd 222
SQL> break on a on b on c on d
SQL> select t1.*, t2.* from t1, t2
2 /
A B C D C1
--- --- --- --- ----------
aaa bbb ccc ddd 111
222
SQL>
Note: in the absence of any further information I opted for a Cartesian product.
edit
BREAK is a SQLPlus command, which suppresses duplicate columns in our rows. It only works in the SQLPlus client. As might be expected, it is covered in Oracle's SQL*Plus User Guide. Find out more.
I used BREAK as an example of the proper way of doing things, because it is clean and correctly implements the separation of concerns. It you are using a different client you would need to use its formatting capabilities. It is possible to tweak the SQL (see below) but that diminishes the utility of the query, because we cannot reuse the query in other places which don't want to suppress the duplicated values.
Anyway, here is one solution which uses the ROW_NUMBER() analytic function in an inline view.
SQL> select * from t1
2 /
A B C D ID
--- --- --- --- ----------
eee fff ggg hhh 1
aaa bbb ccc ddd 2
SQL> select * from t2
2 /
C1 ID
---------- ----------
333 2
111 1
222 2
444 2
SQL> select t1_id
2 , case when rn = 1 then a else null end as a
3 , t2_id
4 , c1
5 from (
6 select t1.id as t1_id
7 , row_number () over (partition by t1.id order by t2.c1) as rn
8 , t1.a
9 , t2.c1
10 , t2.id as t2_id
11 from t1, t2
12 where t1.id = t2.id
13 )
14 order by t1_id, rn
15 /
T1_ID A T2_ID C1
---------- --- ---------- ----------
1 eee 1 111
2 aaa 2 222
2 2 333
2 2 444
SQL>
I chose not to use LAG(), because that only works with fixed offsets, and it seemed likely that the number of rows in T2 would be variable.
Assuning you want all data in a single row, you just do a union select...
Select fieldA from tableA
Union
Select fieldB from TableB
Note that you need to cast the datatype to be the same for both tables.
If you need an other answer, please format the expected result better ;)
Ok...
You have corrected the formating...
In the case above I would simply return 2 cursors from my query. The example data provides no field to link both tables together, so i see no way to join them in a resonable manner. It is possible for a sproc to return several resultsets.
You've done the cartesian product of the two tables since you haven't specified any join criteria. In order to eliminate duplicates, you need to specify how you want the tables to join.
For example, you could try
select * from table1, table2 where table2.val = 111;
Your example doesn't have any join key, so there's no obvious value to join the tables on. But is a more typical example, there would be a related value in both tables so that you could join them together in a meaningful way.
You seem to be doing a cross join here. I suspect you wanted either an equi join or a left outer join.
Related
This is my data:
id
key
nbr of subs
1
ABC
10
1
XXX
3
2
MNO
120
3
ABC
5
3
FGH
110
I need the key for the record (ID) that has the max nbr of subscriptions:
id
key
nbr of subs
1
ABC
10
2
MNO
120
3
FGH
110
I don't mind deleting the extra records, or electing the ones I need and insert them into other table. Any ideas?
SELECT P.Key, MAX(P.[Nbr of Subcriptions])
FROM P
GROUP BY P.Key;
Thank you very much
You need correlated subquery. Try below SQL-
SELECT t1.ID, t1.Key, t1.NBR FROM Table1 as t1
INNER JOIN (SELECT Table1.ID, Max(Table1.NBR) AS MaxOfNBR
FROM Table1 GROUP BY Table1.ID) as t2 ON (t1.NBR = t2.MaxOfNBR) AND (t1.ID = t2.ID);
I try co create a SQL query with two inner joins and an if case. I create an example to explain what I mean:
ID
Typ
Case
123
AAA
zzz
124
BBB
yyy
125
CCC
yyy
Typ1
ID1
AAA
888
BBB
999
CCC
777
ID2
Result
666
1
555
2
777
3
In words, the query should do:
Search in the first table for ID 125, so I get Typ CCC and Case yyy
If case is yyy then search in the second table for CCC in column Typ1, here I get the ID 777 and then search in the third table for 777 in column ID2 to get the result 3.
If case is not yyy then just show me the results of the first table.
The result should be:
ID
Typ
Result
123
AAA
No match
124
BBB
No match
125
CCC
3
I hope you can understand what I try to explain :)
You want to select data from the first table and only show data from the other tables where appropriate. So, outer join the other tables.
select t1.id, t1.typ, t3.result
from t1
left outer join t2 on t2.typ1 = t1.typ and t1.case = 'yyy'
left outer join t3 on t3.id2 = t2.id1
order by t1.id;
I have the below sample data set and I'm trying to come up with a query to find one or more duplicate rows from the same table
TABLE A: with 2 columns as below
CODE_NAME, RESULT
ABC 1
BBC 1
ZZZ 5
ZZZ 6
ZZZ 7
KBC 2
ZBC 2
CCC 2
XYZ 3
MNC 4
And my output should give all the unique rows with duplicate values in the result column such as below
CODE_NAME, RESULT
ABC 1
BBC 1
KBC 2
ZBC 2
CCC 2
i tried below but its not giving me correct result
select A t1, A t2
where A.result = b.result
and a.code_name <> b.code_name
Appreciate other suggestions.
You can use exists:
select t.*
from t
where exists (select 1
from t t2
where t2.result = t.result and t2.code_name <> t.code_name
);
For performance on a large dataset, you want an index on (result, code_name).
You might find it more convenient to have one row per duplicated result:
select result,
listagg(code_name, ',') within group (order by code_name)
from t
group by result
having count(*) > 1;
I need to find missing rows, however, I need data from BOTH tables to be returned. I checked google but did not find a similar question.
TableA
thetime real-time
1 1 pm
2 5 pm
3 7 pm
4 9 pm
5 11 pm
Table2
thedate transaction_num thetime
1/1/2000 111 1
1/1/2000 111 4
1/1/2000 111 5
2/1/2000 111 2
2/1/2000 111 4
2/1/2000 222 1
2/1/2000 222 5
I need to select the date and transaction_num from Table2 that do not have a time in Table1 so the result from the select statement should have the date and trnsaction number for the missing times not in table2:
thedate transaction_num thetime
1/1/2000 111 2
1/1/2000 111 3
2/1/2000 111 1
2/1/2000 111 3
2/1/2000 111 5
2/1/2000 222 2
2/1/2000 222 3
2/1/2000 222 4
This is the code I have but it is giving me a multi-part binding error:
select t2.thedate, t2.transaction_num, t1.thetime
from table2 t2
where not exists(select t1.thetime
from table1 t1
where t2.thetime = t1.thetime)
Does anyone know how to solve this or can point me to an answer?
Most questions in stack overflow for missing rows involve returning data from one table but I need it for 2 tables.
Thank you
It seems all the transaction_nums on all dates should have all the times associated with them. Else it would be treated as missing.
To do this, you can initially cross join the distinct date and transaction_num from table2 and thetime from table1. Then left join on this derived table to get the missing rows.
select tt.thedate, tt.transaction_num,tt.thetime
from (
select * from (
(select distinct thedate,transaction_num from table2) a cross join
(select distinct thetime from table1) b
)
) tt
left join table2 t2 on t2.transaction_num=tt.transaction_num and t2.thetime=tt.thetime and tt.thedate=t2.thedate
where t2.transaction_num is null and t2.thedate is null and t2.thetime is null
Sample Demo
I have 2 tables in SQL Server (ver:2008). Both tables have similar structure. Second table has few extra columns. I want to write a query that displays the differences in these tables (for matching fields). Output should display columns from both tables side by side (for comparison).
I tried using EXCEPT which is displaying the results from table 1 that don't match the results in table2. But I need to display both results side-by-side.
Thank you.
You simply need to select the fields you wish to display:
select t1.*, t2.*
from table1 t1
inner join table2 t2 on t1.ID = t2.ID
where t1.field1 <> t2.field1 OR t1.field2 <> t2.field2
OR ...
For example, if you have 2 tables, Products1 and Products2, both with columns Name, Price, Color etc., and you want to list all different products, you can use this:
SELECT Name FROM Products1
UNION
SELECT Name FROM Products2
OR, you can use FULL JOIN keyword, it returns rows when there is a match in one of the tables. For example:
The “Cars” table:
P_Id Name Color Quality City
---- -------- ----- ------- -----------
1 BMW Red good Las Vegas
2 Lexus Blue bad Los Angeles
3 Mercedes Green good MIami
The "Orders" table:
O_Id OrderNo P_Id
---- ------- ----
1 123 3
2 234 3
3 345 1
4 456 1
5 689 18
Now we want to list all the cars and all the people with their orders.
We use:
SELECT Cars.Name, Cars.Color, Orders.OrderNo
FROM Cars
FULL JOIN Orders
ON Cars.P_Id=Orders.P_Id
ORDER BY Cars.Name
The result:
Cars Color OrderNo
-------- ----- -------
BMW Red 345
BMW Red 456
Mercedes Green 123
Mercedes Green 234
Lexus Blue -
- - 689
Give this a shot. It assumes that there's one column (a) that is identical between the tables, and the rest (b, c, ...) are potentially different.
SELECT t1.a, t2.a, t1.b, t2.b, t1.c, t2.c, ...
FROM table1 t1
JOIN table2 t2
ON t1.a = t2.a
AND NOT (t1.b = t2.b AND t1.c = t2.c ...)
SELECT * FROM
(
SELECT * FROM TABLE1
EXCEPT
SELECT * FROM TABLE2
) T1
UNION ALL
SELECT * FROM
(
SELECT * FROM TABLE2
EXCEPT
SELECT * FROM TABLE1
) T2