how to get combine from Two select statements - sql

my table is,
ID First_Name Last_name manager_ID Unique_ID
12 Jon Doe 25 CN=Jon Doe, DC=test,DC=COM
25 Steve Smith 39 CN=steve smith, DC=test,dc=com
I want to write a sql that will give me manager's unique ID,
select manager_id from test where ID = '12'
this will give me users manager_ID
select unique_id from test where ID = '25'
can i combine above sql in one statement that will give me user's manager's unique_id as output?

You are looking for a self-join:
select m.unique_id
from test t join
test m
on t.manager_id = m.id
where t.ID = 12;
Note that I remove the single quotes around 12. Presumably, id is an integer. You should not be comparing an integer to a string.

Instead of joining it to the same table, you can also make a nested subquery statement like this.
SELECT unique_id FROM test WHERE ID =(SELECT manager_id FROM test WHERE ID = 12);
The inner query outputs the manager_id where id of person equals 12 and the outer query gives the unique_id of the related manager.

Related

How to return all names that appear multiple times in table [duplicate]

This question already has answers here:
What's the SQL query to list all rows that have 2 column sub-rows as duplicates?
(10 answers)
Closed last year.
Suppose I have the following schema:
student(name, siblings)
The related table has names and siblings. Note the number of rows of the same name will appear the same number of times as the number of siblings an individual has. For instance, a table could be as follows:
Jack, Lucy
Jack, Tim
Meaning that Jack has Lucy and Tim as his siblings.
I want to identify an SQL query that reports the names of all students who have 2 or more siblings. My attempt is the following:
select name
from student
where count(name) >= 1;
I'm not sure I'm using count correctly in this SQL query. Can someone please help with identifying the correct SQL query for this?
You're almost there:
select name
from student
group by name
having count(*) > 1;
HAVING is a where clause that runs after grouping is done. In it you can use things that a grouping would make available (like counts and aggregations). By grouping on the name and counting (filtering for >1, if you want two or more, not >=1 because that would include 1) you get the names you want..
This will just deliver "Jack" as a single result (in the example data from the question). If you then want all the detail, like who Jack's siblings are, you can join your grouped, filtered list of names back to the table:
select *
from
student
INNER JOIN
(
select name
from student
group by name
having count(*) > 1
) morethanone ON morethanone.name = student.name
You can't avoid doing this "joining back" because the grouping has thrown the detail away in order to create the group. The only way to get the detail back is to take the name list the group gave you and use it to filter the original detail data again
Full disclosure; it's a bit of a lie to say "can't avoid doing this": SQL Server supports something called a window function, which will effectively perform a grouping in the background and join it back to the detail. Such a query would look like:
select student.*, count(*) over(partition by name) n
from student
And for a table like this:
jack, lucy
jack, tim
jane, bill
jane, fred
jane, tom
john, dave
It would produce:
jack, lucy, 2
jack, tim, 2
jane, bill, 3
jane, fred, 3
jane, tom, 3
john, dave, 1
The rows with jack would have 2 on because there are two jack rows. There are 3 janes, there is 1 john. You could then wrap all that in a subquery and filter for n > 1 which would remove john
select *
from
(
select student.*, count(*) over(partition by name) n
from student
) x
where x.n > 1
If SQL Server didn't have window functions, it would look more like:
select *
from
student
INNER JOIN
(
select name, count(*) as n
from student
group by name
) x ON x.name = student.name
The COUNT(*) OVER(PARTITION BY name) is like a mini "group by name and return the count, then auto join back to the main detail using the name as key" i.e. a short form of the latter query
You can do:
select name
from student as s1
where exists (
select s2
from student as s2
where s1.name = s2.name and s1.siblings != s2.siblings
)
I think the best approach is what 'Caius Jard' mentioned. However, additional way if you want to get how many siblings each name has .
SELECT name, COUNT(*) AS Occurrences
FROM student
GROUP BY name
HAVING (COUNT(*) > 1)
I wanted to share another solution I came up with:
select s1.name
from student s1, student s2
where s1.name = s2.name and s1.sibling != s2.sibling;

How to split select query rows based on the comma separated values in the columns in oracle plsql

I wrote 2 queries Union. i'm getting results as comma separted in two of the columns. And the output is displayed as 2 records.
How to split them into 4 records as below expected results?
select emp_id,dept_name,location from department where dept_id = 1
union
select emp_id,dept_name,location from sales_dept where dept_id = 1;
Output:
emp_id ----- dept_name------ location
r1-----------Retail,IT----- US, UK
k2-----------Sales,Chemical- NZ, SA
j3-----------Biotech(Chemistry,Tech)- JA
I need the expected output as below:
emp_id ----- dept_name-----location
r1-----------Retail--------US
r1-----------IT----------- UK
k2-----------Sales---------NZ
k2-----------Chemical------SA
j3---------Biotech(Chemistry,Tech)--JA
The last record of whereever dept_name is "Biotech(Chemistry,Tech)" should be displayed as single record and not to be split. Please let me know how to do it.
The query given by Jim is working fine except in this scenario when dept_name is Biotech(Chemistry,Tech) as the requirement is given now.
Please use below query,
select emp_id, dept_name, location from
(select distinct emp_id, trim(regexp_substr(dept_name,'[^,]+', 1, level) ) dept_name,
trim(regexp_substr(location,'[^,]+', 1, level) ) location, level
from pivot_comma
connect by regexp_substr(dept_name, '[^,]+', 1, level) is not null
order by emp_id, level);

Need to count the filtered employees

I wrote a query which need filter out the employee data on behalf on their employee codes.
For instance, in my XYZ table i have 200 employees, i need to insert these 200 employee in ABC table, but before inserting, i need to check whether all 200 employees are existed in the system,I first filter out the employee and then insert into my ABC table.
suppose, 180 out of 200 employee matched, then i will insert 180 in the ABC table.
Now i want the count 200-180=20, so i need that difference count.
I wrote a query but it fetches only the matched record, not those employee count who filters out.
Select distinct SD.EMP_code
FROm SALARY_DETAIL_REPORT_012018 SD /*219 Employees*/
JOIN
(SELECT * FROM EMPLOYEE) tbl
ON tbl.EMP_CODE=to_char(SD.EMP_CODE)
WHERE SD.REFERENCE_ID like '1-%';
final output : 213 employees
I want 219-213=6
i want those 6 employees. I also tried INTERSECT but i got same result.
Select distinct to_char(SD.EMP_code)
FROm SALARY_DETAIL_REPORT_012018 SD
WHERE SD.REFERENCE_ID like '1-%'
INTERSECT
SELECT EMP_CODE FROm EMPLOYEE;
OUTPUT
213 Employees
Kindly help me to find out the count of filtered employees
You can use NOT EXISTS :
SELECT DISTINCT SD.EMP_code
FROM SALARY_DETAIL_REPORT_012018 sd
WHERE NOT EXISTS (SELECT 1 FROM EMPLOYEE e WHERE e.EMP_CODE = TO_CHAR(SD.EMP_CODE)) AND
SD.REFERENCE_ID LIKE '1-%';
use except opertaor
Select distinct to_char(SD.EMP_code)
FROM SALARY_DETAIL_REPORT_012018 SD
WHERE SD.REFERENCE_ID like '1-%'
except
SELECT EMP_CODE FROm EMPLOYEE;

sql select tuples and group by id

I have the current database schema
EMPLOYEES
ID | NAME | JOB
JOBS
ID | JOBNAME | PRICE
I want to query so that it goes through each employee, and gets all their jobs, but I want each employee ID to be grouped so that it returns the employee ID followed by all the jobs they have. e.g if employee with ID 1 had jobs with ID, JOBNAME (1, Roofing), (1,Brick laying)
I want it to return something like
1 Roofing Bricklaying
I was trying
SELECT ID,JOBNAME FROM JOBS WHERE ID IN (SELECT ID FROM EMPLOYEES) GROUP BY ID;
but get the error
not a GROUP BY expression
Hope this is clear enough, if not please say and I'll try to explain better
EDIT:
WITH ALL_JOBS AS
(
SELECT ID,LISTAGG(JOBNAME || ' ') WITHIN GROUP (ORDER BY ID) JOBNAMES FROM JOBS GROUP BY ID
)
SELECT ID,JOBNAMES FROM ALL_JOBS A,EMPLOYEES B
WHERE A.ID = B.ID
GROUP BY ID,JOBNAMES;
In the with clause, I am grouping by on ID and concatenating the columns corresponding to an ID(also concatenating with ' ' to distinguish the columns).
For example, if we have
ID NAME
1 Roofing
1 Brick laying
2 Michael
2 Schumacher
we will get the result set as
ID NAME
1 Roofing Brick laying
2 Michael Schumacher
Then, I am join this result set with the EMPLOYEES table on ID.
You need to put JobName to group by expression too.
SELECT ID,JOBNAME FROM JOBS WHERE ID IN (SELECT ID FROM EMPLOYEES) GROUP BY ID,JOBNAME;

write a query to identify discrepancy

I have a table with Student ID's and Student Names. There has been issues with assigning unique Student Id's to students and Hence I want to find the duplicates
Here is the sample Table:
Student ID Student Name
1 Jack
1 John
1 Bill
2 Amanda
2 Molly
3 Ron
4 Matt
5 James
6 Kathy
6 Will
Here I want a third column "Duplicate_Count" to display count of duplicate records.
For e.g. "Duplicate_Count" would display "3" for Student ID = 1 and so on. How can I do this?
Thanks in advance
Select StudentId, Count(*) DupCount
From Table
Group By StudentId
Having Count(*) > 1
Order By Count(*) desc,
Select
aa.StudentId, aa.StudentName, bb.DupCount
from
Table as aa
join
(
Select StudentId, Count(*) as DupCount from Table group by StudentId
) as bb
on aa.StudentId = bb.StudentId
The virtual table gives the count for each StudentId, this is joined back to the original table to add the count to each student record.
If you want to add a column to the table to hold dupcount, this query can be used in an update statement to update that column in the table
This should work:
update mytable
set duplicate_count = (select count(*) from mytable t where t.id = mytable.id)
UPDATE:
As mentioned by #HansUp, adding a new column with the duplicate count probably doesn't make sense, but that really depends on what the OP originally thought of using it for. I'm leaving the answer in case it is of help for someone else.