Display the names of each employees who works in both ‘IT’ and ‘SE’ - sql

Emp(sid(pk) : integer, sname: varchar(255))
Dep(sid(fk) : integer, dep : varchar(255))
SQL:How I find the names of each employees who works in both ‘IT’ and ‘SE’?

To observe a query that Joins two tables together and get common values depend on a common column Ex: id, using INNTER JOIN will help you on that
The INNER JOIN keyword selects records that have matching values in both tables.
Solution
SELECT Emp.sid, Emp.sname FROM Emp
INNER JOIN
(SELECT sid FROM Dep WHERE dep='IT'
INTERSECT
SELECT sid FROM Dep WHERE dep='SE') as A
ON Emp.sid = A.sid
References
SQL INNER JOIN

The way I understand it, the data situation is as below. emp with sid and sname, and dep, with sid - the foreign key to emp and dep, this time not as a table, but a column containing the department's abbreviation. And the combination, in the dep table, of sid and dep, is unique.
If that is the constellation, then join the two tables using sid, filter by: dep in the set:('IT' , 'SE'); Then, put the two columns from emp into the the column list, and GROUP BY them, and finally, apply the grouping filter HAVING COUNT(*) = 2 to just get the group that has two entries when filtered by the two departments.
WITH
emp(sid, sname) AS (
SELECT 42,'Arthur'
UNION ALL SELECT 43,'Ford'
UNION ALL SELECT 44,'Zaphod'
)
,
dep(sid, dep) AS (
SELECT 42,'IT'
UNION ALL SELECT 42,'SE'
UNION ALL SELECT 42,'AC'
UNION ALL SELECT 43,'IT'
UNION ALL SELECT 43,'AC'
UNION ALL SELECT 44,'SE'
UNION ALL SELECT 44,'SA'
)
SELECT
emp.sid
, emp.sname
FROM emp JOIN dep USING(sid)
WHERE dep.dep IN ('IT','SE')
GROUP BY
emp.sid
, emp.sname
HAVING COUNT(*) = 2;
-- out sid|sname
-- out 42|Arthur

Related

How to search for a list of combinations of two columns in a table?

I have a list of combinations from a table (First_Name and Start month of employment).
I need to be able to search the table and determine what entries in the table are not in the list. Ex. (Mark, January exists but Mark, March doesn't.)
Is there a shorter way to do this than append every combination to the SQL? This is a pretty long list out of a pretty large table.
You can CROSS JOIN employee names with list of months to create all possible combinations. LEFT JOIN for the rest:
SELECT
FROM (
SELECT DISTINCT First_Name FROM t
) AS emp
CROSS JOIN (VALUES
('January'), ('February'), ('March'), ('April'), ('May'), ('June'),
('July'), ('August'), ('September'), ('October'), ('November'), ('December')
) mon(Month_Name)
LEFT JOIN t ON emp.First_Name = t.First_Name AND mon.Month_Name = t.Month_Name
WHERE t.PK IS NULL
Use joins to a temporal table or equivalent expressions. Something like
SELECT t.*
FROM ( SELECT 'Mike' AS name, 'March' AS month
UNION SELECT 'John' AS name, 'April' AS month) AS aux
JOIN table t ON t.name = aux.name
AND t.month = aux.name
Of course it can be a literal temporary or standard table if you alredy have the data.
You need a left join or not exists for this. For instance:
select v.*
from (values ('Mark', 'January'), ('Mark', 'March')) v(name, mon)
where not exists (select 1
from t
where t.name = v.name and t.mon = v.mon
);

SQL Sub query and case statment

I got unique ID's from POS table by using the below code where now I need to get the address information next to it comparing them with customer master table.
select
subqueries.id
from
(
select (cust_key) as id from dbo.pos
union
select (disti_key) as id from dbo.pos
union
select (reseller_key) as id from dbo.pos
)subqueries
I assumed that the customer master table has a primary key column id and let it have the name customers
select subqueries.id, c.adress
from (select (cust_key) as id from pos
union
select (disti_key) as id from pos
union
select (reseller_key) as id from pos
) subqueries
join customers c on subqueries.id = c.id

How to create an sql command that has SELECT statements from 2 different tables?

How to create an sql command that has SELECT statements from 2 different tables? For example,
select ID from EMP_details, select job_id from Jobs_details
So how can i possibly merge both into one
Selecting from two or more tables When rows in them tables has some sort of relation so you want to extract the corresponding row you would use a JOIN something like this ....
JOIN
SELECT EMP.ID, JD.job_id
FROM EMP_details EMP INNER JOIN jobs_details JD
ON EMP.CommonColumn = JD.CommonColumn
Results From Two SELECTS
When you have two SELECT statements and just want to get the results returned from them queries into one row you can do something like this ...
SELECT X.A , Y.B
FROM (select ID AS A from EMP_details) X, (select job_id AS B from Jobs_details) Y
This is known as a JOIN in SQL. Your query might look like this:
SELECT EMP_details.ID,
EMP_details.Name,
Job_details.RefNumber
FROM EMP_details,
Jobs_details
WHERE EMP_details.ID = Jobs_details.job_id;
Having a column in both tables by which you can match the rows from the first table to the second one, like for example the job_id in Jobs_details matches job_id in Emp_details, you could do:
SELECT e.ID,j.job_id
FROM EMP_details e
INNER JOIN jobs_details j ON e.job_id = j.job_id
For more information on JOIN's see the documentation.
Have you try
SELECT id FROM (SELECT id FROM EMP_details UNION ALL SELECT id FROM Jobs_details) as temp_table;
Thanks,

SQL Multiple Duplicate Row Detection

I'm trying to determine a correct way to isolate rows within a table that have the same values in 2 columns.
There are two tables, one (Name) with the person's names and IDs, and the other one (Nation) with people's IDs and their nations. I join the two tables with inner join, and now the new table columns consist of an ID, first name, last name, and nation. If I want to find pairs of people who have the same last name and are from the same nation, why isn't
select ID, FName, LName, Nation
from (Name inner join Nation on Name.ID = Nation.ID)
group by Name, Nation
having count(Name) > 1 and count(Nation) > 1
working?
I'm aiming for the result to be a table with columns:
ID -------First--------------- Last ---------Nation
where the last names and nations will be identical pairs while first names will be different.
I feel like the group by part isnt appropriate, but is there even an alternate way? Thanks for any help.
If you are using MS SQL Server:
select
*
from
(
select
Name.*,
Nation.Nation,
cnt = count(*) over(partition by LName, Nation)
from Name
join Nation on Nation.ID = Name.ID
) t
where cnt > 1
Try this:
SELECT * FROM (
SELECT Name.ID, Name.FName, Name.LName, Nation.Nation
FROM Name
INNER JOIN Nation ON (Name.ID = Nation.ID)
) a
INNER JOIN (
SELECT Name.ID, Name.FName, Name.LName, Nation.Nation
FROM Name
INNER JOIN Nation ON (Name.ID = Nation.ID)
) b ON (a.LName = b.LName AND a.Nation = b.Nation)
WHERE a.ID < b.ID
As Simon Righarts hinted, something's not right with the design.
Scenario 1)
If a name can have multiple nations, you would have 3 tables implementing an n:m relationship.
CREATE TABLE name (name_id int, name text, ...);
CREATE TABLE nation (nation_id int, nation text, ...);
CREATE TABLE nationality (name_id int references name(name_id)
,nation_id int references nation(nation_id)
... );
Query for the scenario:
SELECT a.name_id, a.fname, a.lname, n.nation
FROM name a
JOIN nationality na USING (name_id)
JOIN nation n USING (nation_id)
JOIN (
SELECT a.lname, na.nation_id
FROM name a
JOIN nationality na USING (name_id)
GROUP BY 1,2
HAVING count(*) > 1) x USING (lname, nation_id)
Scenario 2)
If a name can only have one nation, there would be a column nation_id in the table name:
CREATE TABLE name (name_id int
,name text
,nation_id int references nation(nation_id), ...);
CREATE TABLE nation (nation_id int, nation text, ...);
Query for this scenario:
SELECT a.name_id, a.fname, a.lname, n.nation
FROM name a
JOIN nation n USING (nation_id)
JOIN (
SELECT a.lname, a.nation_id
FROM name a
GROUP BY 1,2
HAVING count(*) > 1) x USING (lname, nation_id);
All multiple occurrences are included here, not just "pairs" - assuming you meant that.
Your actual description doesn't fit either scenario.

How to combine three SELECT statements with very tricky requirements

I have a SQL query with three SELECT statements. A picture of the data tables generated by these three select statements is located at www.britestudent.com/pub/1.png. Each of the three data tables have identical columns. I want to combine these three tables into one table such that:
(1) All rows in top table (Table1) are always included.
(2) Rows in the middle table (Table2) are included only when the values in column1 (UserName) and column4 (CourseName) do not match with any row from Table1. Both columns need to match for the row in Table2 to not be included.
(3) Rows in the bottom table (Table3) are included only when the value in column4 (CourseName) is not already in any row of the results from combining Table1 and Table2.
I have had success in implementing (1) and (2) with an SQL query like this:
SELECT DISTINCT
UserName AS UserName,
MAX(AmountUsed) AS AmountUsed,
MAX(AnsweredCorrectly) AS AnsweredCorrectly,
CourseName,
MAX(course_code) AS course_code,
MAX(NoOfQuestionsInCourse) AS NoOfQuestionsInCourse,
MAX(NoOfQuestionSetsInCourse) AS NoOfQuestionSetsInCourse
FROM
( "SELECT statement 1" UNION "SELECT statement 2" ) dt_derivedTable_1
GROUP BY CourseName, UserName
Where "SELECT statement 1" is the query that generates Table1 and "SELECT statement 2" is the query that generates Table2. A picture of the data table generated by this query is located at www.britestudent.com/pub/2.png. I can get away with using the MAX() function because values in the AmountUsed and AnsweredCorrectly columns in Table1 will always be larger than those in Table2 (and they are identical in the last three columns of both tables).
What I fail at is implementing (3). Any suggestions on how to do this will be appreciated. It is tricky because the UserName values in Table3 are null, and because the CourseName values in the combined Table1 and Table2 results are not unique (but they are unique in Table3).
After implementing (3), the final table should look like the table in picture 2.png with the addition of the last row from Table3 (the row with the CourseName value starting with "4. Klasse..."
I have tried to implement (3) using another derived table using SELECT, MAX() and UNION, but I could not get it to work. Below is my full SQL query with the lines from this failed attempt to implement (3) commented out.
Cheers,
Frederick
PS--I am new to this forum (and new to SQL as well), but I have had more of my previous problems answered by reading other people's posts on this forum than from reading any other forum or Web site. This forum is a great resources.
-- SELECT DISTINCT MAX(UserName), MAX(AmountUsed) AS AmountUsed, MAX(AnsweredCorrectly) AS AnsweredCorrectly, CourseName, MAX(course_code) AS course_code, MAX(NoOfQuestionsInCourse) AS NoOfQuestionsInCourse, MAX(NoOfQuestionSetsInCourse) AS NoOfQuestionSetsInCourse
-- FROM (
SELECT DISTINCT UserName AS UserName, MAX(AmountUsed) AS AmountUsed, MAX(AnsweredCorrectly) AS AnsweredCorrectly, CourseName, MAX(course_code) AS course_code, MAX(NoOfQuestionsInCourse) AS NoOfQuestionsInCourse, MAX(NoOfQuestionSetsInCourse) AS NoOfQuestionSetsInCourse
FROM (
-- Table 1 - All UserAccount/Course combinations that have had quizzez.
SELECT DISTINCT dbo.win_user.user_name AS UserName,
cast(dbo.GetAmountUsed(dbo.session_header.win_user_id, dbo.course.course_id, dbo.course.no_of_questionsets_in_course) as nvarchar(10)) AS AmountUsed,
Isnull(cast(dbo.GetAnswerCorrectly(dbo.session_header.win_user_id, dbo.course.course_id, dbo.question_set.no_of_questions) as nvarchar(10)),0) AS AnsweredCorrectly,
dbo.course.course_name AS CourseName,
dbo.course.course_code,
dbo.course.no_of_questions_in_course AS NoOfQuestionsInCourse,
dbo.course.no_of_questionsets_in_course AS NoOfQuestionSetsInCourse
FROM dbo.session_detail
INNER JOIN dbo.session_header ON dbo.session_detail.session_header_id = dbo.session_header.session_header_id
INNER JOIN dbo.win_user ON dbo.session_header.win_user_id = dbo.win_user.win_user_id
INNER JOIN dbo.win_user_course ON dbo.win_user_course.win_user_id = dbo.win_user.win_user_id
INNER JOIN dbo.question_set ON dbo.session_header.question_set_id = dbo.question_set.question_set_id
RIGHT OUTER JOIN dbo.course ON dbo.win_user_course.course_id = dbo.course.course_id
WHERE (dbo.session_detail.no_of_attempts = 1 OR dbo.session_detail.no_of_attempts IS NULL)
AND (dbo.session_detail.is_correct = 1 OR dbo.session_detail.is_correct IS NULL)
AND (dbo.win_user_course.is_active = 'True')
GROUP BY dbo.win_user.user_name, dbo.course.course_name, dbo.question_set.no_of_questions, dbo.course.no_of_questions_in_course,
dbo.course.no_of_questionsets_in_course, dbo.session_header.win_user_id, dbo.course.course_id, dbo.course.course_code
UNION ALL
-- Table 2 - All UserAccount/Course combinations that do or do not have quizzes but where the Course is selected for quizzes for that User Account.
SELECT dbo.win_user.user_name AS UserName,
-1 AS AmountUsed,
-1 AS AnsweredCorrectly,
dbo.course.course_name AS CourseName,
dbo.course.course_code,
dbo.course.no_of_questions_in_course AS NoOfQuestionsInCourse,
dbo.course.no_of_questionsets_in_course AS NoOfQuestionSetsInCourse
FROM dbo.win_user_course
INNER JOIN dbo.win_user ON dbo.win_user_course.win_user_id = dbo.win_user.win_user_id
RIGHT OUTER JOIN dbo.course ON dbo.win_user_course.course_id = dbo.course.course_id
WHERE (dbo.win_user_course.is_active = 'True')
GROUP BY dbo.win_user.user_name, dbo.course.course_name, dbo.course.no_of_questions_in_course,
dbo.course.no_of_questionsets_in_course, dbo.course.course_id, dbo.course.course_code
) dt_derivedTable_1
GROUP BY CourseName, UserName
-- UNION ALL
-- Table 3 - All Courses.
-- SELECT DISTINCT null AS UserName,
-- -2 AS AmountUsed,
-- -2 AS AnsweredCorrectly,
-- dbo.course.course_name AS CourseName,
-- dbo.course.course_code,
-- dbo.course.no_of_questions_in_course AS NoOfQuestionsInCourse,
-- dbo.course.no_of_questionsets_in_course AS NoOfQuestionSetsInCourse
-- FROM dbo.course
-- WHERE is_active = 'True'
-- ) dt_derivedTable_2
-- GROUP BY CourseName
-- ORDER BY CourseName
With such filtering requirements (depending on the rows of prior queries), I recommend a table variable.
DECLARE #MyTable TABLE
(
ID int PRIMARY KEY,
Name varchar(50),
QueryNumber int
)
INSERT INTO #MyTable (ID, Name, QueryNumber)
SELECT CustomerID, CustomerName, 1
FROM Customer
WHERE Name = "Bob"
INSERT INTO #MyTable (ID, Name, QueryNumber)
SELECT CustomerID, CustomerName, 2
FROM Customer
WHERE Name = "Joe" and CustomerID not in (SELECT ID FROM #MyTable)
INSERT INTO #MyTable (ID, Name, QueryNumber)
SELECT CustomerID, CustomerName, 3
FROM Customer
WHERE CustomerID not in (SELECT ID FROM #MyTable)
SELECT *
FROM #MyTable
Here is an Oracle flavored solution:
Select
*
from table1
UNION
select
*
from table2
where not exists(
select 'x'
from table1
where
table2.username = table1.username
and table2.coursename = table1.coursename
)
UNION
select
*
from table3
where
coursename not in (
Select
coursename
from table1
UNION /* the union operator implies distinct, so
there will be no duplicates */
select
coursename
from table2
where not exists(
select 'x'
from table1
where
table2.username = table1.username
and table2.coursename = table1.coursename
)
)