My question is about left outer join with counter. I have two tables.
employee:
empid empname
----- -------
101 Tom
102 Jerry
103 Jack
104 Tim
allocation:
generator analyzer tester
--------- -------- ------
101 102 103
103 102 101
102 101 104
I need following result
empid empname generator analyzer tester
------ ------- --------- -------- -------
101 Tom 1 1 1
102 Jerry 1 2 0
103 Jack 1 0 1
104 Tim 0 0 1
I need to count the values of each task. Tom has generated 1, analyzed 1
and tested 1. Like that i need to count the values. Is this possible in
SQL. If this is possible please help me to get output.
I am getting the result. but it is not expected. I have used outer joins to solve the problem,
select
e.empid,
e.empname,
count(a1.generator),
count(a2.analyzer),
count(a3.tester)
from employee e
left join allocation a1
on e.empid=a1.author
left join allocation a2
on e.empid=a2.reviewer
left join allocation a3
on e.empid=a3.tester
group by
e.empid,
e.empname;
You can achieve it with this:
Select empid,sum(generaor),sum(analyzer),sum(tester)
from
(
Select empid,count(a.generaor) generaor,0 analyzer,0 tester
from employee
JOIN Allocation a on empid=a.generaor group by empid,a.generaor
UNION
Select empid,0 generaor,count(b.analyzer)analyzer,0 tester
from employee
JOIN Allocation b on empid=b.analyzer group by empid,b.analyzer
UNION
Select empid,0 generaor,0 analyzer,count(c.tester) tester
from employee
JOIN Allocation c on empid=c.tester group by empid,c.tester
) stag
group by empid
Try this
SELECT empid, empname, sum(generator), sum(analyzer), sum(tester) FROM
(SELECT e.empid, e.empname, count(a1.generator) generator, 0 analyzer, 0 tester
FROM Employee e
JOIN Allocation a1 ON a1.generator = e.empid
GROUP BY e.empname
UNION
SELECT e.empid, e.empname, 0 generator, count(a2.analyzer) analyzer, 0 tester
FROM Employee e
JOIN Allocation a2 ON a2.analyzer = e.empid
GROUP BY e.empname
UNION
SELECT e.empid, e.empname, 0 generator, 0 analyzer, count(a3.tester) tester
FROM Employee e
JOIN Allocation a3 ON a3.tester = e.empid
GROUP BY e.empname) tmp
GROUP BY empname
ORDER BY empid
Related
following are the table in database.
many to many relations between train and passenger
table 1 name=train
TNO TNAMe
1 x
2 y
3 z
table 2 name=passenger
PNO PNAME
111 a
222 b
333 c
table 3 name=tp
TNO PNO TPDATE
1 111 23-NOV-15
2 222 24-JUN-14
3 222 19-JUN-13
1 333 23-NOV-15
using follwing code i only find out which train number has highest frequency
select tno,count(tno) as numberofoccurance from tp group by tno
Try to use group by and row_number analytical function as following:
Select name, tp_date
From
(Select t.tname tp.tp_date,
row_number() over (partition by tp.tp_date order by count(1) desc nulls last) as cnt
From train t
Join tp tp
On (t.id = tp.tno)
Group by tp.tno, tp.tp_date)
Where cnt = 1;
Cheers!!
I have a table X
ID A B
--------------
1 abc 27
1 - 28
2 - 33
3 xyz 41
3 - 07
I need output as
ID A B
--------------
1 abc 27
2 - 33
3 xyz 41
I tried doing
max(A) OVER (PARTITION BY ID) as the_value
but it did not work. I can still see all the rows in the output table.
I was wondering if somebody has come across a similar situation and has a solution to this ?
you can use this simple trick for getting the full record for which some column is maxed:
select original.* from
(select ID,max(B) as B from Tbl group by ID ) maxB
inner join
(select * from Tbl ) original
on original.ID = maxB.ID and original.B = maxB.B
now this is of course an overkill code. you can also do:
select Tbl.* from
(select ID,max(B) as B from Tbl group by ID ) maxB
inner join
Tbl
on Tbl.ID = maxB.ID and Tbl.B = maxB.B
but the first version is more of a template to do whatever you want with further columns, fields, conditions joins etc.
I have an employee with multiple managers. The manager name field has (firstname,lastname) and the email field has(last.first#email.com).There is no Mgr id.
So, when I try to group this by employee id to get the max of Mgr name and email, some times I end up getting the wrong name/email id combination.
ex:
person Mgr_name Mgr_email
------- --------- ----------
111 brad,pitt pitt.brad#test.com
111 mike,clark clark.mike#test.com
when I group it by person and get the max(mgr_name),mgr_email, I get
person max(Mgr_name) max(Mgr_email)
------- --------- ----------
111 mike,clark pitt.brad#test.com
How do I get the correct email/name combination?
Use row_number analytical function instead:
with t(person ,Mgr_name , Mgr_email) as (
select 111 ,'brad,pitt' , 'pitt.brad#test.com' from dual union all
select 111 ,'mike,clark' , 'clark.mike#test.com' from dual )
select person ,Mgr_name , Mgr_email from (
select t1.*, row_number() over (order by mgr_name) num from t t1)
where num = 1
This get max mgr_name with correct email.
Output:
PERSON MGR_NAME MGR_EMAIL
---------- ---------- -------------------
111 brad,pitt pitt.brad#test.com
You could use a subselect to obtain the max mgr_name for each person in the table then join it back to the base results to limit to only display each persons "Max" manager...
SELECT t1.Person, t1.Mgr_name, t1.mgr_email
FROM tableName t1
INNER JOIN (Select max(mgr_name) mname, Person from TableName group by person) t2
on t1.mgr_name = t2.mname
and t2.Person = T1.Person
I have below data in a table called data_tab
sn code
2 101
2
2 202
5 103
5
5
How can i query to see result in one row, like
sn code1 code2 code3
2 101 202
5 103
Hi This gives the intented output ... take a look here
select sn,
max(decode(rn,1,code)) as CODE_1
,max(decode(rn,2,code)) as CODE_2
,max(decode(rn,3,code)) as CODE_3
from
(
select sn,
code,
row_number() over (partition by sn order by null ) rn
from test
)
group by sn
I have more experience with MySQL and MSSQL but I don't consider myself a SQL expert.
I have a requirement for some SQL work running on an Oracle database. Not even sure the version yet but it should be somewhat recent (10, 11??).
Anyway, I have to count the number of distinct records that spans two tables. For sake of argument, let's call them master and detail.
The following SQL gives me the number I want against the data. However, this SQL will eventually be put in a UDF (or Oracle equivalent). But my question is, is there a better way? Either using some advanced Oracle optimization or even just a better SQL query.
Thanks
select count(*) from
(
select
mas.barcode
, det.barcode_val
from mas
inner join det on (det.trans_id = mas.trans_id and mas.trans_sub_id = det.trans_sub_id)
where
mas.trans_id = 12345
and det.code_type = 'COMMODORE'
group by
mas.barcode
, det.barcode_val
);
Data:
MAS
trans_id trans_sub_id barcode
-------------------------------------
12345 1 COM_A
12345 2 COM_A
12345 3 COM_B
DET
trans_id trans_sub_id code_type barcode_val
-------------------------------------------------------
12345 1 COMMODORE C64
12345 1 COMMODORE C64
12345 1 TANDY TRASH80
12345 2 COMMODORE C128
12345 2 ATARI 800XL
12345 2 COMMODORE AMIGA500
12345 3 COMMODORE C64
Results before count
--------------------
COM_A C64
COM_A C128
COM_A AMIGA500
COM_B C64
Results after count
-------------------
4
SELECT
COUNT(DISTINCT mas.barcode || det.barcode_val)
FROM mas
INNER JOIN det
ON (det.trans_id = mas.trans_id and mas.trans_sub_id = det.trans_sub_id)
WHERE
mas.trans_id = 12345
AND det.code_type = 'COMMODORE'
or
SELECT COUNT(*) FROM (
SELECT DISTINCT mas.barcode, det.barcode_val
FROM mas
INNER JOIN det
ON (det.trans_id = mas.trans_id and mas.trans_sub_id = det.trans_sub_id)
WHERE
mas.trans_id = 12345
AND det.code_type = 'COMMODORE'
)
If you use the
COUNT(DISTINCT mas.barcode || det.barcode_val)
make sure to put a delimiter between the pipeline:
COUNT(DISTINCT mas.barcode || '-' || det.barcode_val)
For example imagine the following scenario:
Column1 Column2 Column1 || Column2 Column1 || '-' || Column2
A B AB A-B
AB <null> AB AB-
1 201 1201 1-201
<null> 1201 1201 -1201
This table has 4 rows with 4 different values. But if you try a
COUNT(DISTINCT COLUMN1 || COLUMN2)
you would get just 2 "distinct" groups.
Just a tip to try to avoid those corner cases.