How to fetch data from two table in one go - sql

I have a requirement where I have to fetch data from database table.
Condition is,
There are two tables with identical columns like name, mobile, address, age.
Ex. table names like Student and Teacher.
now if I don't find anything in student table then I will retrieve data from Teacher table.
how to write this query ?

To get results from the two tables you would use UNION ALL. Here however you only want to access table Teacher when there are no matching rows in table Student. This is slightly more difficult. You can still use UNION ALL, but need an EXISTS clause on your teacher query.
select * from student
union all
select * from teacher where not exists (select * from student);

Related

MS ACCESS Query with junction table, for all items in one table, but not in another

To create a many-to-many relationship, I have three tables:
tblEmployee, contains employees
tlkpPermission, contains 11 different possible permission groups an employee can be part of
tblEmployeeXPermission, combines the EmployeeID with one or more PermissionID
What I’m trying to create is a query that shows what permission groups an employee is NOT part of.
So, if EmployeeID 12345 is associated with PermissionID 1,2,3,4,5, but NOT 6,7,8,9,10,11 (in the EmployeeXPermission table) then I want the query to show EmployeeID 12345 is not part of PermissionID 6,7,8,9,10,11.
Of all the JOINs and query options, I can only get a query to show which PermissionIDs an employee is associated with, but not the PermissionIDs the employee is not associated with.
Any help would be appreciated.
Thanks
You need to start with all combinations of employees and permissions, and this type of join is CROSS JOIN, but MsAccess SQL does not have it in the new SQL syntax. You can use the old syntax of listing your tables in the FROM clause, comma separated, and provide the join condition, if any, in the WHERE clause:
SELECT
EmployeeId,
PermissionID
FROM
tblEmployee as E,
tlkpPermission as P
where not exists (
select 1
from tblEmployeeXPermission X
where X.EmployeeId=E.EmployeeId
and X.PermissionId=P.PermissionId
)
Here the part up to the WHERE clause would give you all employee - permission combinations, and the WHERE clause removes those occuring in the tblEmployeeXPermission, leaving you with the ones you want.

SQL Remove Duplicate Rows of Data from Query Result

I am still learning the ropes of SQL so I have run into my first obstacle. I am to create an SQL query that retrieves employee.firstname, employee.lastname, dependents.depname, and dependents.birthday from the two tables employees and dependents.
I am only supposed to show an employee if he or she has a dependent.
My primary table (employee; only the first 43 rows): employee table
My secondary table (dependents): dependents table
This is what I have so far:
SELECT
employee.firstname, employee.lastname,
dependents.depname, dependents.birthday
FROM
employee
INNER JOIN
dependents ON employee.id = dependents.empid
This works fine however I run into many duplicate rows of data:
Original Query
This is not the full query result but I think it provides sufficient evidence of my problem.
I used the DISTINCT keyword with my SELECT statement, but it only retrieved a small number of my dependents.
Adding DISTINCT
Have you already any duplicates in one of the tables employee or dependents? The second result looks correct. With select distinct the database removes all duplicates from the result set.

SQL query to select records that have one value in a column but missing another value

I have a database that has two tables. One holds the name of the classes a student can take (class_id, class_desc) and the other has the students information (id, fname, lname, class_id). I join the tables to get a roster of who is taking what class by joining on the class_id. How do I go about getting a roster of students that are taking class 'cl_2055' but not taking class 'cl_6910'?
You really need to change your schema if you can. You should have three tables. Student, Class and StudentClass, (StudentClass contains a pointer to each of the other tables.
But if you insist on using the schema you have...
SELECT
*
FROM
students
WHERE
class_id = 'cl_2055'
AND id NOT IN (SELECT id FROM students where class_id = 'cl_6910')
This assumes the id is not unique, and you are using ID to represent students. If you are using ID to represent records, then you will need the second approach:
SELECT
*
FROM
students students_in_2055
WHERE
class_id = 'cl_2055'
AND NOT EXISTS (
SELECT 1
FROM students students_in_6910
WHERE students_in_6910.class_id = 'cl_6910'
AND students_in_2055.fname = students_in_6910.fname
AND students_in_2055.lname = students_in_6910.lname
)
I like to use aggregation for this purpose
select si.fname, si.lname
from studentinformation si
where ci.classid in ('cl_2055', 'cl_6910')
group by si.fname, si.lname
having min(ci.classid) = 'cl_2055' and max(ci.classid) = 'cl_2055';
First, this assumes that the class identifiers are the ids and not the description (seems logical to me). If they are the descriptions, then you need to join in the class information.
How does this work? The where clause filters down to students who might be in both classes. The group by aggregates to a single row per student. And the having keeps students who are only in "cl_055".

Retrieving duplicate and original rows from a table using sql query

Say I have a student table with the following fields - student id, student name, age, gender, marks, class.Assume that due to some error, there are multiple entries corresponding to each student. My requirement is to identify the duplicate rows in the table and the filter criterion is the student name and the class.But in the query result, in addition to identifying the duplicate records, I also need to find the original student detail which got duplicated. Is there any method to do this. I went through this answer: SQL: How to find duplicates based on two fields?. But here it only specifies how to find the duplicate rows and not a means to identify the actual row that was duplicated. Kindly throw some light on the possible solution. Thanks.
First of all: if the columns you've listed are all in the same table, it looks like your database structure could use some normalization.
In terms of your question: I'm assuming your StudentID field is a database generated, primary key and so has not been duplicated. (If this is not the case, I think you have bigger problems than just duplicates).
I'm also assuming the duplicate row has a higher value for StudentID than the original row.
I think the following should work (Note: I haven't created a table to verify this so it might not be perfect straight away. If it doesn't it should be fairly close)
select dup.StudentID as DuplicateStudentID
dup.StudentName, dup.Age, dup.Gender, dup.Marks, dup.Class,
orig.StudentID as OriginalStudentId
from StudentTable dup
inner join (
-- Find first student record for each unique combination
select Min(StudentId) as StudentID, StudentName, Age, Gender, Marks, Class
from StudentTable t
group by StudentName, Age, Gender, Marks, Class
) orig on dup.StudentName = orig.StudenName
and dup.Age = orig.Age
and dup.Gender = orig.Gender
and dup.Marks = orig.Marks
and dup.Class = orig.Class
and dup.StudentID > orig.StudentID -- Don't identify the original record as a duplicate

SQL query where data from one table = data from another

I have 2 tables: person_concern and person. They both have a code column and person has a dept column. I want to select data from person_concern table where the dept column in person table = 30.
Basically the person table has a different code for each row and then the person is put in a department. So i can have multiple rows in the person table with the same dept field.
The person_concern table is for writing problem concerns for people. It has a code to know which person its referring to which id get from the person table. So i want to select data from that person_concern table where the code matches the code from the person table and that person is from a certain dept such as 30.
Hope that makes sense... Here's what ive tried so far but get an invalid number error.
select
PERSON_CONCERNS.CODE
PERSON_CONCERNS.ENTRY_DATE
PERSON_CONCERNS.ENTRY_OPR
PERSON_CONCERNS.DISCUSSION
from PERSON_CONCERNS
inner join PERSON on PERSON_CONCERNS.CODE = PERSON.CODE
where PERSON.DEPT = 30
I think you are just missing the commas on your field names but need to see the actual code you are running along with the create table statements and some sample data to be sure.
select
PERSON_CONCERNS.CODE,
PERSON_CONCERNS.ENTRY_DATE,
PERSON_CONCERNS.ENTRY_OPR,
PERSON_CONCERNS.DISCUSSION,
from PERSON_CONCERNS
inner join PERSON on PERSON_CONCERNS.CODE = PERSON.CODE
where PERSON.DEPT = 30