SQL query for getting the value ,based on a condition - sql

Hi I need a help to get one sql Query. I have one table 'EMP' .
id name mid
1 A 1
2 B 1
3 C 2
4 D 1
5 E 2
I want the result as
id name mid
1 A A
2 B A
3 C B
4 D A
5 E B
can any one help me to do this.

It is a simple self join:
select id, t1.name, t2.name from emp t1 join emp t2 on t1.mid=t2.id

using inner join:
select EMP1.id, EMP1.name, EMP2.name AS MID from EMP AS EMP1 INNER JOIN EMP AS EMP2 on EMP1.mid=EMP2.id
ORDER BY EMP1.ID

Beside #alex answer you can also try these two too:
Method 1
SELECT T.Id ,T.Name ,D.Name AS mid
FROM EMP AS D
CROSS APPLY (SELECT Id ,Name FROM EMP AS T WHERE mid = D.id) AS T;
Method 2
SELECT Id ,Name ,(SELECT Name FROM EMP WHERE id = T.mid) AS mid
FROM EMP AS T;

Related

join two sql table as column

i have two tables as below:
firsttable
id
cat_id
name
1
2
name_01
2
2
name_02
3
1
name_03
4
3
name_04
5
3
name_04
secondtable
id
name
1
cat_01
2
cat_02
3
cat_03
my question is how can i create below table result?
id(secondtable)
name(secondtable)
count(firsttable)
1
cat_01
1
2
cat_02
2
3
cat_03
2
select t2.id,t2.name,
(select count(*) from firsttable t1 where t1.cat_id=t2.id )as count
from secendtable t2;
Just using standard aggregation
select
s.id,
s.name,
count(*)
from firsttable f
join secondtable s
on f.cat_id = s.id
group by s.id, s.name order by s.id
It's very Simple like that
SELECT s.id,s.name, (SELECT count(*)
FROM `firsttable` AS f
WHERE f.cat_id = s.id ) as count
FROM `secondtable` AS s

How to get Oracle to return unique results in a one to many relationship tables with a left join

I have a three tables
Table 1
Id Department
1 A
2 B
3 C
4 D
Table 2
Id DepartId Name
1 1 ABC
2 1 DEF
3 1 ASD
4 2 FGH
5 2 HJK
6 3 ZXC
Table 3
Id Depart Area
1 A pp
2 B
3 C nn
4 D oo
I need the result
Id Depart Name Area
1 A ABC pp
2 B FGH Null
3 C ZXC nn
4 D NULL oo
I need one matching entry from table 2 and table 3 to corresponding entry in the table 1
Do a left join to also get t1 rows without any reference in the t2 table. GROUP BY to get only 1 row per Department.
select t1.id, t1.Department, min(t2.Name)
from t1
left join t2 on t1.id = t2.DepartId
group by t1.id, t1.Department
I think I would do this with a correlated subquery:
select t1.*,
(select t2.name
from t2
where t1.id = t2.DepartId and rownum = 1
) as t2name
from t1;
This saves the overhead of an aggregation. An index on t2(DepartId, name) is optimal for this query.
by the way not the answer to your specific question but if instead of just one you want all the names you can use listagg
SELECT t1.id,
department,
LISTAGG (name, ',') WITHIN GROUP (ORDER BY name) names
FROM t1, t2
WHERE t1.id = t2.departId(+)
GROUP BY t1.id, department
ORDER BY 1
ID Department Names
1 A ABC,ASD,DEF
2 B FGH, HJK
3 C ZXC
4 D

Update table property from a value in a same table

I have an Employee Data table with following properties
Id Emp_name Supervisor_Name Supervisor_id
1 A B
2 B
3 C B
I want to update the Supervisor_Id column with Id value equal to Supervisor_Name. The output will be as follows.
Id Emp_name Supervisor_Name Supervisor_id
1 A B 2
2 B
3 C B 2
What is the optimum SQL query to do this
Self join would do the job
update e1
set e1.Supervisor_id=e.id
from Employee e1
join Employee e
on e1.Supervisor_Name =e.Emp_name
Use UPDATE with INNER JOIN syntax:
UPDATE t1
SET t1.Supervisor_id = t2.Id
FROM mytable t1
INNER JOIN mytable t2 ON t1.Supervisor_Name = t2.Emp_name
Demo here

how to select distinct values from two tables limit to one row

I have two tables with this values:
**table 1**
id name value
1 A 1
2 B 1
3 F 2
4 G 3
**table 2**
id name value
1 C 1
2 D 1
3 E 2
If I do an inner join of both tables by the value I´m getting this:
A C
A D
B C
B D
F E
But, the problem is that I want only distinct values from both columns like that:
A C
B D
F E
Another set of posible result will be:
A D
B C
F E
There´s no chance of name of table 1 will appear in table 2.
If one value from a column was already selected, it can´t be selected again. This example will be an error because C was already selected:
A C
B C
F E
Any ideas?
In order to pair the records, you need a running number per value to link with. Use row_number() for this.
select t1.name as t1_name, t2.name as t2_name
from
(
select name, value, row_number() over (partition by value order by name) as rn
from table1
) t1
join
(
select name, value, row_number() over (partition by value order by name) as rn
from table2
) t2
on t1.value = t2.value and t1.rn = t2.rn;
SQL fiddle: http://www.sqlfiddle.com/#!4/75de0/1.
Based on the data you provided, and the column you're using to join, you're getting the results you should be getting.
To get your desired results, you would need to join on id, not value
as such:
select a.id, a.name, b.name
from tableA a
inner join tableB b on a.id = b.id

SQL Server matching all rows from Table1 with all rows from Table2

someone please help me with this query,
i have 2 tables
Employee
EmployeeID LanguageID
1 1
1 2
1 3
2 1
2 3
3 1
3 2
4 1
4 2
4 3
Task
TaskID LanguageID LangaugeRequired
1 1 1
1 2 0
2 1 1
2 2 1
2 3 1
3 2 0
3 3 1
LangaugeID is connected to table langauge (this table is for explaination only)
LangaugeID LanguageName
1 English
2 French
3 Italian
is there a possilbe way to make a query which gets employees where they can speak all the languages required for each task?
for example:
Task ID 1 requires only LanguageID = 1, so the result should be EmployeeID 1,2,3,4
Task ID 2 requires all 3 languages, so the result should be EmployeeID 1,4
Task ID 3 requires only LanguageID = 3, so the result should be EmployeeID 1,2,4
here is another variant to do this:
select t1.taskid, t2.employeeid from
(
select a.taskid, count(distinct a.languageid) as lang_cnt
from
task as a
where a.LangaugeRequired=1
group by a.taskid
) as t1
left outer join
(
select a.taskid, b.employeeid, count(distinct b.languageid) as lang_cnt
from
task as a
inner join
employee as b
on (a.LangaugeRequired=1 and a.languageid=b.languageid)
group by a.taskid, b.employeeid
) as t2
on (t1.taskid=t2.taskid and t1.lang_cnt=t2.lang_cnt)
###
here you can insert where statement, like:
where t1.taskid=1 and t2.employeeid=1
if such query returns row - this employee can work with this task, if no rows - no
###
order by t1.taskid, t2.employeeid
as you see, this query creates two temporary tables and then joins them.
first table (t1) calculates how many languages are required for each task
second table (t2) finds all employees who has at least 1 language required for task, groups by task/employee to find how many languages can be taken by this employee
the main query performs LEFT JOIN, as there can be situations when no employees can perform task
here is the output:
task employee
1 1
1 2
1 3
1 4
2 1
2 4
3 1
3 2
3 4
update: simpler, but less correct variant, because it will not return tasks without possible employees
select a.taskid, b.employeeid, count(distinct b.languageid) as lang_cnt
from
task as a
inner join
employee as b
on (a.LangaugeRequired=1 and a.languageid=b.languageid)
group by a.taskid, b.employeeid
having count(distinct b.languageid) = (select count(distinct c.languageid) from task as c where c.LangaugeRequired=1 and c.taskid=a.taskid)
Another version using NOT EXISTS
Retrieve all task-employee combinations where a missing language does not exist
SELECT t1.EmployeeId, t2.TaskId
FROM (
SELECT DISTINCT EmployeeID
FROM Employee
) t1 , (
SELECT DISTINCT TaskID
FROM Task
) t2
WHERE NOT EXISTS (
SELECT 1 FROM Task t
LEFT JOIN Employee e
ON e.EmployeeID = t1.EmployeeID
AND e.LanguageID = t.LanguageID
WHERE t.TaskID = t2.TaskID
AND LanguageRequired = 1
AND e.EmployeeID IS NULL
)
http://www.sqlfiddle.com/#!6/e3c78/1
You could use a Join logic to get the result, something like:
SELECT a.EmployeeID FROM Employee a, Task b WHERE b.LanguageRequired == a.LanguageID;