I have three tables with the following structures:
User Table
UserID Name Age
------ ---- ---
001 AA 23
002 BB 25
003 CC 30
004 DD 24
005 EE 23
temp_User Table
UserID Name Age
------ ---- ---
001 AA 23
002 BB 25
004 DD 24
005 EE 23
007 GG 23
009 HH 28
ExceptionUsers Table
UserID Status
------ --------
021 Active
002 Inactive
004 Active
010 Active
012 Inactive
I used the following query to retrieve my result:
Query
select
A.Name
,B.Name
,A.Age
,B.Age
from User A
inner join temp_User B
on A.UserID = B.UserID
left join ExceptionUsers C
on A.UserID = C.UserID
and C.Status = 'Inactive'
order by
A.Name
Result
001 AA 23
002 BB 25
005 EE 23
But the result includes users who are 'Active'.
001 AA 23
002 BB 25
004 DD 24
005 EE 23
How can I try the query to get my result?
Move C.Status = 'Inactive' to the where clause.
I'd move the LEFT JOIN logic to the WHERE clause, to a NOT EXISTS.
select A.Name, B.Name, A.Age, B.Age
from User A
inner join temp_User B
on A.UserID = B.UserID
where not exists (select * from ExceptionUsers C
where A.UserID = C.UserID
and C.Status = 'active')
order by A.Name
Left join does not filter the data provided on joining condition.
So you may move the joining condition and C.Status = 'Inactive' to where clause and it treats as inner join
select A.Name, B.Name, A.Age, B.Age
from User A
inner join temp_User B
on A.UserID = B.UserID
left join ExceptionUsers C
on A.UserID = C.UserID
where
C.Status = 'Inactive'
order by A.Name
you can use the below query to get the list of active user with their details.
select * from temp_User where UserID in (select UserID from ExceptionUsers where Status = 'Inactive')
Related
I have a condition where i get the users data from table A or table B wherever the data exists.
I cannot write a condition in java but it has to be done totally in oracle and result set sent to UI.
How can i do this in oracle sql.
Users table:
userId firstName LastName MI
11 AAA 111 A1
12 BBB 222 B2
TableA
UserId ROLE firstName LastName MI Grade
11 MANAGER AAA 111 A1 A1
TableB
UserId ROLE firstName LastName MI Grade
12 LEAD BBB 222 B2 A4
OutPut should be:
UserId FirstName LastName MI ROLE Grade
11 AAA 111 A1 MANAGER A1
12 BBB 222 B2 LEAD A4
Select * from users u, tableA a, tableB b
where u.userId = a.userId
and u.userId = b.userId
and u.userId = :userId
Where :userId is the data passed from UI.
I have to get the data from tableA 1st and only when not found I have to get from tableB
Should I do a union or join which is more efficient?
You can try to use UNION ALL on tableA and tableB, then do JOIN instead of ,(CROSS JOIN)
SELECT u,*,t1.ROLE,t1.Grade
FROM (
SELECT UserId ,ROLE ,Grade
FROM tableA
UNION ALL
SELECT UserId ,ROLE,Grade
FROM tableB
) t1 INNER JOIN users u
ON u.UserId = t1.UserId
I would use left join:
select u.*,
(case when a.userid is not null then 'MANAGER' else 'LEAD' end) as role,
coalesce(a.grade, b.grade) as grade
from users u left join
tablea a
on a.userid = u.userid left join
tableb b
on b.userid = u.userid;
one contain multiple columns and test two tables have one columns.
Table: Client
Name age Benefit Id code value
Tom 33 AA 0A 1 12
Tom 33 AB 0C 1 13
Tom 33 AA 0C 5 11
Sam 31 CC 0B 3 10
Rik 28 EE 0D 5 9
Table2: Sell
Code1
1
4
Table3: tip
Code2
5
6
I want output as Name,Age, Benefit, Id and Code, which code present in both table "sell" and "tip".
Name Age Benefit Id code Approved
Tom 33 AA 0A 1 7
Tom 33 AA 0C 5 11
Code I have written as
------Break code-----------
Create table #temp1 as
select c.* from Client c inner join Sell s on c.code1 = s.code
where Benifit= AA
Create table #temp2 as
select c.* from Client c inner join Sell s on c.code2 = s.code
where Benifit= AA
Create table #combine as
select ss.* ,
,case when ss.value > 5 then ss.value- 5 Else 0 approved
from #temp1 ss inner join #temp2 ff
On ss.Name= ff.Name
AND ss.Age= ff.Age
where Benifit= 'AA'
Group by ss.Name Age
------------------------------------------------
----Since 3 table are created with repeated logic, I have put Above code is put into one code, even thought it is not optimized ----------------
select ss.Name, ss.age
,case when ss.value > 5 then ss.value- 5 Else 0 approved
from
(select * from Client c inner join Sell s on c.code1 = s.code
where Benifit= AA) ss
inner join
(select * from Client cc inner join Tip t on cc.code2 = t.code
where Benifit= AA) ff
On ss.Name= ff.Name
AND ss.Age= ff.Age
Group by Name Age
So, I have two problem:
I want Benefit, Id, code and value beside Name and Age, since current query not allow to do that as 'Group By' is used
I am using two select multiple inner join as below
a. (select * from Client c inner join Sell s on c.code = s.code1
where Benifit= AA) ss
b. (select * from Client cc inner join Tip t on cc.code2 = t.code
where Benifit= AA) ff
but I don't want my code to repeatedly use the same code as above is repeated.
A new column Approved is created by subtracting 5 from Value column
Note: The output will Inner join based on "Name" and "Age" between
Inner join of Client & Sell
Inner join between Client & Tip
Please suggest.
Note I want Name, Age having code in both 'Sell' and 'Tip' where Benifit= AA Although output will be from "Sell".
I think you want a query like this -
SELECT C.Name, C.Age, C.Benefit, C.Id, C.Code, (C.Value - 5) Approved
FROM Client C
INNER JOIN Sell S ON C.Code = S.Code1
INNER JOIN Tip T ON S.Code1 = T.Code2
WHERE C.Benefit = 'AA'
I have the below 2 tables
Table Name: Port
City Code
------------------
City A 001
City B 002
City C 003
City D 004
City E 005
City F 006
City G 007
Table Name: Shipments
Code Shipments
------------------
001 5
001 4
002 2
003 4
003 3
003 4
004 1
005 1
006 1
007 2
I want to get the list of Cities where maximum shipments take place.
Answer:
City Total Shipments
------------------------
City C 11
City D 1
City E 1
City F 1
Can someone help me with the SQL query for this.
select c.city as City, sum(s.shipments) as Shipments
from
port c
inner join
shipments s on s.code = c.code
group by c.code
order by sum(s.shipments) asc;
Check this out and let me know.
You can use a Common Table Expression (CTE) to first aggregate the shipments for each City. The min and max records can then be returned as follows:
WITH cte AS ( SELECT P.city AS City,
SUM(S.shipments) AS TotalShipments
FROM Port P
INNER JOIN Shipments S ON S.code = P.code
GROUP BY P.city )
SELECT *
FROM cte c
WHERE c.TotalShipments IN ( SELECT MAX(c2.TotalShipments) RequiredTotalShipments
FROM cte c2
UNION
SELECT MIN(c3.TotalShipments)
FROM cte c3 )
I have a query that returns records as below
vw_EmployeeReferenceNumbers
NAME Number
---- ------
AA 123
AA 234
AA 456
I have another table that returns records like so
AllEmployees
AllNames
----------
AA
BB
CC
I want to output a recordset like so
NAME Number
---- ------
AA 123
AA 234
AA 456
BB 123
BB 234
BB 456
CC 123
CC 234
CC 456
I dont want to use Cursors at all. I cant modify the view vw_EmployeeReferenceNumbers or the table AllEmployees. Can this be done in SQL?
What I have so far that doesn't work is:
select name, number
from
(select Name, number, 1 as id from vw_EmployeeReferenceNumbers
) as A
left join
(select name, 1 as id from AllEmployees
) as B
on A.id = B.id
Use cross join:
select e.name, ern.number
from AllEmployees e cross join
vw_EmployeeReferenceNumbers ern;
SELECT e.name,
ern.number
FROM AllEmployees e INNER JOIN
EmployeeReferenceNumbers ern ON 1=1
ORDER BY e.name
If I want to display Order_Number data1 data2 data3 (most current by date changed OtherData1, OtherData2, OtherData3) date_changed the problem is I wasn't just one line, I was getting multiple lines for each order number.
What I would love to get is
1, a, f,q, cc,ccc,abc, 12/2/2014, bob
3, c, b,h, aa,aaa,abc, 12/2/2014, bob
Thanks!
I was working with
SELECT
t.Order_Number,
cr.data1, cr.data2, cr.data3,
t.OtherData1, t.OtherData2, t.OtherData3,
x.date_changed, cr.name
FROM
(SELECT
Order_Number,
Max(date_changed) as date_changed
FROM
table2
GROUP BY
Order_Number) x
JOIN
table2 t ON x.date_changed = t.date_changed
LEFT JOIN
table1 cr ON x.Order_Number = cr.Order_Number
WHERE cr.name = 'bob'
Here are example tables.
Table1:
Order_Number data1 data2 data3 name
1 a f q bob
2 b g g john
3 c b h bob
4 d s j john
Table2:
Order_Number date_changed OtherData1 OtherData2 OtherData3
1 11/30/2014 aa aaa abc
1 12/1/2014 bb bbb def
1 12/2/2014 cc ccc abc
3 12/1/2014 dd aaa def
2 11/30/2014 dd bbb abc
2 12/1/2014 ss ccc def
3 12/2/2014 aa aaa abc
4 11/26/2014 fc wer wsd
Your Join to config_log (Table2) needs to include the entire composite key if you want to retrieve unique rows.
JOIN
conf_log t ON x.date_changed = t.date_changed
And x.Order_Number = t.Order_number
I think you need to have 2 sub querys:
SELECT
Data.Order_Number,
Data.data1, Data.data2, Data.data3,
Data.OtherData1, Data.OtherData2, Data.OtherData3,
Data.date_changed, Data.name
FROM
(SELECT
Order_Number,
Max(date_changed) as date_changed
FROM
table2
GROUP BY
Order_Number) x
JOIN (SELECT
t.Order_Number,
cr.data1, cr.data2, cr.data3,
t.OtherData1, t.OtherData2, t.OtherData3,
t.date_changed, cr.name
FROM table2 t
JOIN table1 cr
ON t.Order_Number = cr.Order_Number) AS Data
ON x.date_changed = data.date_changed
AND x.Order_Number = data.Order_number
WHERE cr.name = 'bob'
The fact that you had cr.name in the where clause means the LEFT JOIN had the same affect as just JOIN.