adding a where condition for one criteria in sql query - sql

I need to add a where condition for a SQL query , means when the dept id become 9 only i need that where condition , else i dont required.
i have written the below query , is the approach is correct?
SELECT
b.DeptId,
b.DeptName,
a.SurveyID,
a.SurveyName,
a.Status,
a.AllUsers,
IsNull(a.SelectedUsers,'') as SelectedUsers,
a.OpenDate,
a.CloseDate,
e.Role as RoleName
from Surveys a
inner join Departments b
on a.deptid=b.deptid
left outer join
surveyUsers c
on c.surveyid=a.SurveyID
and c.empCode= 9902
left outer join [360HRSurveyEmployee] d
on d.surveyid=a.SurveyID
left outer join [360HRSurvey] e
on e.sempid = c.empCode
and e.empid = d.empid
where ( c.empCode= 9902 or a.AllUsers = 1 )
and a.status in (1)
and a.OpenDate <= '6/9/2015'
and a.CloseDate >= '6/9/2015'
and CASE WHEN DeptId == 9
THEN e.Role IS NOT NULL END
order by b.DeptID,a.SurveyID
Note the last three lines in the above query where i added the case :
and CASE WHEN DeptId == 9
THEN e.Role IS NOT NULL END
order by b.DeptID,a.SurveyID
I am getting a syntax error also
Incorrect syntax near '='.

If I understand you correctly, you only need rows where DeptId is not 9, or DeptId is not null. Also, your gross disregard for consistency in your capitalization hurts me. What is this beast?!
SELECT
b.DeptID, b.DeptName,
a.SurveyID, a.SurveyName, a.Status, a.AllUsers,
ISNULL(a.SelectedUsers,'') as SelectedUsers,
a.OpenDate, a.CloseDate, e.Role as RoleName
FROM
Surveys AS a
INNER JOIN Departments AS b
ON a.DeptID = b.DeptID
LEFT OUTER JOIN SurveyUsers AS c
ON (c.SurveyID = a.SurveyID AND c.EmpCode = 9902)
LEFT OUTER JOIN [360HRSurveyEmployee] AS d
ON d.SurveyID = a.SurveyID
LEFT OUTER JOIN [360HRSurvey] AS e
ON (e.EmpID = c.EmpCode AND e.EmpID = d.EmpID)
WHERE
(
c.EmpCode = 9902
OR a.AllUsers = 1
)
AND a.Status = 1
AND a.OpenDate <= '6/9/2015'
AND a.CloseDate >= '6/9/2015'
AND (
a.DeptID != 9
OR e.Role IS NOT NULL
)
ORDER BY
a.DeptID,
a.SurveyID;

and CASE WHEN DeptId == 9
You only need one = sign for this comparison.

You need to use single =
CASE WHEN DeptId = 9
THEN e.Role END
What exactly do you want to achive with this line? THEN e.Role IS NOT NULL END

Related

LEFT OUTER JOIN WITH inner join with case in SQL DBMS

I have the following query
SELECT
A.WORKNR AS "WORK-nr",
UCASE(A.NAME) AS "NAME" ,
UCASE(A.ADRESS) AS "adress",
A.ZIPNR,
UCASE(A.ZIPADR) AS "zipadress",
A.NNR,
CASE
WHEN AO.ORG_REF IS NULL THEN 'OK'
ELSE 'NO '
END AS RESULT OF ORG ,
CASE
WHEN B.B = 1 THEN 'OK'
ELSE 'COME WITH ANOTHER NNR'
END AS COMPARE_RESULT
FROM
WORK.WORK_ADRESS A
LEFT JOIN
(SELECT
POSTNR, UCASE(STREET) AS STREET,
COUNT(DISTINCT NNR) AS B
FROM
WORK.WORK_ADRESS
GROUP BY
ZIPNR, UCASE(STREET)) B ON B.STREET = UCASE(A.STREET)
AND B.ZIPNR = ZIPNR
LEFT JOIN
(SELECT *
FROM WORK.ORGANISATION2) AO ON AO.WORK_REF = A.WORK_REF
AND AO.TILL >= CURRENT DATE
what I want is to add a JOIN to a third table ORG3 that contains the name for org genom
SELECT WORK.ORGANISATION2
INNER JOIN STYR.ORG2 ORG3 ON AO.ORG_REF3 = ORG3.ORG_REF
and get the column OR3.NAME as a separate column.
Can anyone help me? I am thankful

Rewrite union query to a single query

I wondered if it was possible to write this as one query:
SELECT * FROM
(SELECT "markets".*
FROM "markets"
INNER JOIN "positions" ON "positions"."id" = "markets"."position_id"
INNER JOIN "players" ON "players"."id" = "positions"."player_id"
INNER JOIN "other_players" ON "other_players"."id" = "players"."other_player_id"
WHERE (markets.updated_at > '2021-01-10 11:50:14.136015')
AND "markets"."on_feed" = true
AND "markets"."deleted_at" IS NULL
UNION
SELECT "markets".*
FROM "markets"
WHERE (markets.updated_at > '2021-01-10 11:50:14.136015')
AND "markets"."on_feed" = true
AND "markets"."deleted_at" IS NOT NULL) results
ORDER BY results.updated_at DESC
There's a lot of overlap in the two queries. In the first one we want all markets that have those associations in place. For the 2nd query we don't really care if the associations are there or not.
SELECT * FROM "markets"
LEFT JOIN "positions" ON "positions"."id" = "markets"."position_id"
LEFT JOIN "players" ON "players"."id" = "positions"."player_id"
LEFT JOIN "other_players" ON "other_players"."id" = "players"."other_player_id"
WHERE markets.updated_at > '2021-01-10 11:50:14.136015'
AND "markets"."on_feed" = true
AND ("markets"."deleted_at" IS NOT NULL
OR "positions"."id" IS NOT NULL AND "players"."id" IS NOT NULL
AND "other_players"."id" IS NOT NULL)
ORDER BY markets.updated_at DESC
Use EXISTS instead:
SELECT m.*
FROM "markets" m
WHERE m.updated_at > '2021-01-10 11:50:14.136015' AND
markets."on_feed" = true AND
(m."deleted_at" IS NOT NULL OR
EXISTS (SELECT 1
FROM "positions" p JOIN
"players" pl
ON pl."id" = p."player_id" JOIN
"other_players" op
ON op."id" = p."other_player_id"
WHERE p."id" = m."position_id"
)
)
ORDER BY m.updated_at DESC

Select from column including null values

I'm trying to create SELECT that includes various foreign key to list all the rows it has, but there is two foreign key that can be null.
bank_id and bbank_id can be null, so with this example it only will list rows that doesn't have null values in bank_id and bbank_id, but I need it to return rows where bank_id and bbank_id are null or not null.
I tried using IS NOT NULL AND NULL, well it doesn't work.
SELECT E.emp_id, E.emp_name, E.emp_surname1, E.emp_surname2,
J.job_name, U.ubi_name, D.dep_name, POR.por_type,
B.bank_name, BB.bbank_name
FROM public.employee E, public.ubi U,
public.jobs J, public.department D,
public.percenttable POR, public.bank B,
public.bbank BB
WHERE E.ubi_id = U.ubi_id AND E.job_id = J.job_id
AND E.dep_id = D.dep_id AND E.por_id = POR.por_id
AND E.bank_id = B.bank_id AND E.bbank_id = BB.bbank_id
AND E.ubi_id IS NOT NULL AND E.job_id IS NOT NULL AND E.dep_id IS NOT NULL
AND E.por_id IS NOT NULL AND E.bank_id IS NOT NULL AND E.bbank_id IS NOT NULL
ORDER BY E.emp_id ASC;
I read something about using LEFT JOIN but no idea how to implement it here.
You need to use modern JOIN syntax defined in the SQL-92 standard, 27 years ago. Here's how your query should look using left outer joins:
select
e.emp_id, e.emp_name, e.emp_surname1, e.emp_surname2,
j.job_name, u.ubi_name, d.dep_name, por.por_type,
b.bank_name, bb.bbank_name
from public.employee e
left join public.ubi u on e.ubi_id = u.ubi_id
left join public.jobs j on e.job_id = j.job_id
left join public.department d on e.dep_id = d.dep_id
left join public.percent por on e.por_id = por.por_id
left join public.bank b on e.bank_id = b.bank_id
left join public.bbank bb on e.bbank_id = bb.bbank_id
where e.ubi_id is not null
and e.job_id is not null
and e.dep_id is not null
and e.por_id is not null
-- and e.bank_id is not null -- removed per your requirement
-- and e.bbank_id is not null -- removed per your requirement
order by e.emp_id asc
Welcome to the 21st century! ;-)

SQL left join issue with null values

I inherited a query that uses left joins. One of the things the query is doing is removing any archived records, that is where archived = 'Y'. This is how the query looks:
select P.firstname, E.entityid, C.committeeid, L.locationname
from Pract P
left join Committee C
on P.commiteeid = C.committeeid
and c.archived = 'N'
left join Entity E
on P.entityid = E.EntityID
and e.archived = 'N'
left join Location L
on E.location = L.location
and l.archived = 'N'
The result should only return records where archived <> 'Y'. I think a problem with putting the filter with the "on" is that it will return a record where c.archived = 'N' and just put a null in the archived field, which is not correct:
FirstName EntityID CommitteeId
John 55 null
If c.archived = 'Y' then the record should not show up.
I believe the archived filter should be in the where clause, like this:
select firstname, entityid, committeeid
from Pract P
left join Committee C
on P.commiteeid = C.committeeid
left join Entity E
on P.entityid = E.entityid
left join Location L
on E.Locationid = L.locationid
where c.archived = 'N'
and e.archived = 'N'
and l.archived = 'N'
The problem I'm finding is that there are instances where the archived field from Committee is null(it's not a 'Y' or an 'N'). Using my solution incorrectly eliminates the records since null <> 'N.'
If I try this:
where c.archived <> 'Y'
it does not work, I'm guessing because NULL does not evaluate to anything.
If I try this:
where (c.archived = 'N' or c.archived is null)
it doesn't work as it now brings back those null records caused by the left join. I can't replace the left join with an inner join because that will exclude records where c.committeeid is null.
I just want to bring back records where archived <> 'Y', which includes those where the field is null.
To be clear, this is what the records in the table can look like:
FirstName EntityID Archived
John 55 Y
Tom 56 NULL
Rob 57 N
In this instance I want the returned records to look like:
Tom 56 NULL
Rob 57 N
John would be eliminated because Archived = 'Y.'
Is there another way to do this?
If I understand correctly, you want to use another field in the where clause for the filtering:
select firstname, entityid, committeeid -- this will return an error on committeeid
from Pract P left join
Committee C
on P.commiteeid = C.committeeid and
(c.archived <> 'Y' or c.archived is null)
where c.committeeid is not null;
You may also be able to do this with exists more easily:
select p.*
from Pract P
where not exists (select 1
from Committee C
where P.commiteeid = C.committeeid and
c.archived = 'Y'
);
This handles the NULL values automagically.
I believe that you are looking for this version. You just start with what you had and modify joining condition to cover values that are not equal to Y and that are NULL.
select firstname, entityid, committeeid
from Pract P
left join Committee C
on P.commiteeid = C.committeeid
and (c.archived <> 'Y' OR c.archived IS NULL)
Then if you need only items that has record in commitee table. you put it in WHERE clause.
WHERE P.commiteeeid = C.commiteeid
But it will just emulate INNER JOIN.
Your problem with comparing NULL is that you can't use <> to test for NULL values. If you want records with NULL values you have to test for IS NULL explicitly.
So your updated query would look like:
select P.firstname, E.entityid, C.committeeid, L.locationname
from Pract P
left join Committee C
on P.commiteeid = C.committeeid
and (c.archived <> 'Y' OR c.archived IS NULL)
left join Entity E
on P.entityid = E.EntityID
and (e.archived <> 'Y' OR e.archived IS NULL)
left join Location L
on E.location = L.location
and (l.archived <> 'Y' OR l.archived IS NULL)
And if you have only values 'Y' 'N' and NULL, then you can also use
and (c.archived = 'N' OR c.archived IS NULL)
Just to be sure we understand each other here is minimal example for your query
create table Pract (firstname varchar(20), cid int)
create table comt ( cid int, archived varchar(1) )
insert into Pract values ('Tom',1),('Adam',2),('Mark',3),('Bob',4)
insert into comt values (1,'Y'), (2,'N'), (3,NULL)
--
select firstname, P.cid, C.cid, C.archived
from Pract P
LEFT join comt C
on P.cid = C.cid
and (c.archived <> 'Y' OR c.archived IS NULL)
With result
firstname cid cid archived
1 Tom 1 NULL NULL
2 Adam 2 2 N
3 Mark 3 3 NULL
4 Bob 4 NULL NULL
Or with INNER JOIN
select firstname, P.cid, C.cid, C.archived
from Pract P
INNER join comt C
on P.cid = C.cid
and (c.archived <> 'Y' OR c.archived IS NULL)
With result
firstname cid cid archived
1 Adam 2 2 N
2 Mark 3 3 NULL
The solution depends on how you want to handle the NULL values from the left join. If NULL means not archived then
select firstname, entityid, committeeid
from Pract P
left join Committee C
on P.commiteeid = C.committeeid
left join Entity E
on P.entityid = E.entityid
left join Location L
on E.Locationid = L.locationid
where (c.archived = 'N' OR c.archived IS null)
and (e.archived = 'N' OR e.archived IS null)
and (l.archived = 'N' OR l.archived IS NULL)

How can I select a column from a NOT-IN sub-query

Here is a query that I need help with:
SELECT s.lastfirst, s.student_number, s.grade_level
FROM students s
WHERE s.schoolid = 300 AND s.enroll_status = 0 AND s.id not in
(
SELECT d.studentid
FROM section_meeting em INNER JOIN sections e
ON em.sectionid = e.id
INNER JOIN cc d ON e.id = d.sectionid
WHERE em.schoolid = 300 and em.period_number in (P1)
)
This query works fine except that I need to show the column em.period_number in the results as well. Can anyone suggest how to go about it?
Thanks!
query works fine exept that I need to show the column em.period_number
in the results as well
If you have successfully got the result using your question query let me add period_number with join query..try :
SELECT s.lastfirst, s.student_number, s.grade_level, section_meeting.period_number
FROM students s INNER JOIN
section_meeting ON s.schoolid = section_meeting.schoolid
WHERE (s.schoolid = 300) AND (s.enroll_status = 0) AND (s.id NOT IN
(SELECT d.studentid
FROM section_meeting em INNER JOIN
sections e ON em.sectionid = e.id INNER JOIN
cc d ON e.id = d.sectionid
WHERE (em.schoolid = 300) AND (em.period_number IN (P1))))