SQL - ISNULL Record Value - sql

I have a SQL Statement where i need to display the value from another table if a joining record exists. To attempt this, I'm using ISNULL. As a demonstration, here is a sample query:
SELECT
FirstName,
LastName,
ISNULL(select top 1 birthdate from BirthRecords where [SSN]=p.SSN, false) as HasRecord
FROM
Person p
Please note, this is a small snippet. I know there is a better way to do this specific query. However, I cannot do an outer join in my FROM clause. Because of this, I'm trying to do an inline statement. I thought ISNULL was the correct approach. Can someone please explain how I should do this?
Thank you,

Try this and see if it works for ya.
SELECT
FirstName,
LastName,
CASE when R.BirthDate IS NULL THEN FALSE
ELSE TRUE
END as HasRecord
FROM
Person p
left join BirthRecords R on p.SSN = R.SSN

Use a left outer join to return the birthdate if it exists, otherwise null:
SELECT
FirstName,
LastName,
birthdate
FROM Person AS p
LEFT JOIN BirthRecords AS b ON p.SSN = b.SSN

Your question is incomplete. You should at least specify:
what DBMS you use (I guess MS SQL Server, because of ISNULL)
what does/does not work
That said, I don't think you can use ISNULL like this. According to the docs, the replacement and the original column must be type compatible. So you cannot use "false" as the replacement, it must be a date (like birthdate).

Doing a JOIN is really your best bet from a performance and readability perspective.
Why can you not do a JOIN?
Another option is to create a FUNCTION and call it. Something like GET_BIRTHDATE(p.SSN) and it would return a scaler value of null or the date. This is clearly a performance issue because the function will get called on every row...so the JOIN would still be better.

Related

ERROR:ORA-00979: not a GROUP BY expression

select frstname,addr
from medication,patient
where medication.patientnum=patient.ptnum
group by frstname,addr
having finish_date='29-01-20';
how do i solve this error?
It is very unclear what the purpose of your query is.
An immediate fix is to move the condition form the having clause to the where clause, because the column it uses is not part of the group by clause - and to use proper join syntax and date litterals:
select frstname, addr
from medication m
inner join patient p on m.patientnum = p.ptnum
where finish_date = date '2020-01-29'
group by frstname, addr
I would also warmly recommend prefixing each column with the table it belongs to, using the table aliases that I added to the query (m for medication, p for patient).
This might, or might not, do what you actually intend. If not, then you should probably ask a new question, providing sample data, expected results, and an explanation of what you are trying to accomplish.

Getting value from a table and add value from table 2 if excist

I'm new to SQL and im wondering if something like this is possible.
It's probably a super simple solution but i cant seem to solve it. I'm using an Oracle database.
Employee_Table:
employeeNr
username
address
epost
Computer_Table:
employeeNr
ComputerNumber
ComputerUpdated
When I'm using
SELECT *
From Employee_Table,
Computer_Table
WHERE Employee_Table.EmployeeNr = Computer_Table.EmployeeNr
AND Employee_Table.username LIKE ('%SomeUsername%')
When I'm using this sqlstring I only get users with computers. I would like to get all users and the computers of those who has one.
Now the million dollar question. What modifications do I need to make?
Never use commas in the FROM clause. Always use explicit JOIN.
In this case, you want a LEFT JOIN:
SELECT *
FROM Employee_Table e LEFT JOIN
Computer_Table c
ON c.EmployeeNr = c.EmployeeNr
WHERE e.username LIKE '%SomeUsername%';
When you use LEFT JOIN, conditions on the first table go on the WHERE clause. Conditions on the second table go in the ON clause.

How do I write a subquery using a JOIN in SQL

I have the following code to retrieve and display the first and last names of writers who are also editors (ED_ID = WRT_ID).
SELECT Writers.WRT_LastName AS LastName, Writers.WRT_FirstName AS FirstName
FROM Writers INNER JOIN Editors ON Editors.ED_ID = Writers.WRT_ID;
It produces the results I want, but how would I write it using a subquery and produce the same results?
I am using Access 2013
Let me know if I need to provide more info.
Presumably, you don't want duplicate results. I point that out, because the subquery is going to be different from the join if the Editors table has duplicates.
Typical ways of writing this are using IN or EXISTS. I tend to go with the latter, although the two are usually pretty equivalent performance wise (on the other hand, NOT EXISTS is preferable to NOT IN semantically).
SELECT Writers.WRT_LastName AS LastName, Writers.WRT_FirstName AS FirstName
FROM Writers
WHERE EXISTS (SELECT 1 FROM Editors WHERE Editors.ED_ID = Writers.WRT_ID);
You just need to put the join conditions into a where clause subquery:
SELECT WRT_LastName as LastName, WRT_FirstName as FirstName
FROM WRITERS
WHERE WRT_ID in (SELECT ED_ID FROM EDITORS)

Do subselects do an implicit join?

I have a sql query that seems to work but I dont really understand why. Therefore I would very much appreciate if someone could help explain whats going on:
THE QUERY RETURNS: All organisations that dont have any comments that were not created by the consultant who created the organisation record.
SELECT \"organisations\".*
FROM \"organisations\"
WHERE \"organisations\".\"id\" NOT IN
(SELECT \"comments\".\"commentable_id\"
FROM \"comments\"
WHERE \"comments\".\"commentable_type\" = 'Organisation'
AND (comments.author_id != organisations.consultant_id)
ORDER BY \"comments\".\"created_at\" ASC
)
It seems to do so correctly.
The part I dont understand is why (comments.author_id != organisations.consultant_id) is working!? I dont understand how postgres even knows what "organisations" is inside that subselect? It is not defined in here.
If this was written as a join where I had joined comments to organisations then I would totally understand how you could do something like this but in this case its a subselect. How does it know how to map the comments and organisations table and exclude the ones where (comments.author_id != organisations.consultant_id)
That subselect happens in a row so it can see all columns of that row. You will probably get better performance with this
select organisations.*
from organisations
where not exists (
select 1
from comments
where
commentable_type = 'organisation' and
author_id != organisations.consultant_id
)
Notice that it is not necessary to qualify commentable_type since the one in comments has priority over any other outside the subselect. And if comments does not have a consultant_id column then it would be possible to take its qualifier out, although not recommended for better legibility.
The order by in your query buys you nothing, just added cost.
You are running a correlated subquery. http://technet.microsoft.com/en-us/library/ms187638(v=sql.105).aspx
This is commonly used in all databases. A subquery in the WHERE clause can refer to tables used in the parent query, and they often do.
That being said, your current query could likely be written better.
Here is one way, using an outer join with comments, where no matches are found based on your criteria -
select o.*
from organizations o
left join comments c
on c.commentable_type <> 'Organisation'
and c.author_id = o.consultant_id
where c.commentable_id is null

Use of 1=2 in a SQL query

Someone please explain the meaning of '1=2' in the below SQL query.
SELECT E.EmpID,
E.EmpName,
Country = CASE
WHEN T.Active = 'N'
AND 1 = 2 THEN 'Not Working Anymore'
ELSE C.Country_Name
END,
T.Contract_No
FROM Employees E (nolock)
INNER JOIN Contract T
ON T.Contract_No = E.Contract_No
LEFT JOIN Country C (nolock)
ON E.Country_ID = C.Country_ID
thanks
EDIT:- Corrected the slight mistake existed in the example SQL query given by me.
# ALL :- The query mentioned here is an example version of a big working query on which I have to reoslve something. I have created a sample scenario of SQL query for the sake of simplicity of question.
There is a good use for this 1=2 part of the WHERE clause if you are creating a table from another, but you don't want to copy any rows. For example:
CREATE TABLE ABC_TEMP AS
SELECT * FROM ABC WHERE 1=2;
when T.Active = 'N' and 1=2 then 'Not Working Anymore'
Simple, the above condition will never become true.
So the result will always be C.Country_Name
It is a common trick used in dynamic construction of SQL filter clauses. This allows the automated construction of "T.Active = 'N' and" with no check needed for a following clause, because "1=2" will always be appended.
Update:
Whether 1=1 or 1=2 is used depends on whether conjunctive or disjunctive normal form is supposed to be used in building the automated clauses. In this case, there seems to have been a mismatch of design and implementation.
Update 2
I believe most developers prefer conjunctive normal form, with major terms joind by AND, but disjunctive normal form is equal in expressive power and size of code.
It corresponds to a FALSE argument.
For example ;
select * from TABLE where 1=2
returns zero rows.
Use WHERE 1=2 if you don't want to retrieve any rows,
As 1=2 is always false.
adding and 1=2 will cause that case to always return false. To find out why it's there, ask the person who put it there.
I suspect it was put there so the author could force the first condition to be false and then he forgot to remove it.
I would guess that is a debug script. It is there to always return the negative part of the case. Probably on release that part is taken out.
1 = 2 means that we are giving a condition that will always be false; therefore no records will show ('NULL') for your rows...
ie
Create table empt_tgt
AS
Select empno, ename, job, mgr, sal
WHERE 1=2;
then assuming that empt_tgt has records for all those columns
when we perform the following statement:
SELECT * FROM empt_tgt
EMPT_TGT will be null ; meaning we will only see the column name empno, ename, job, mgr,sal no data...
I have found this in several bits of code at my company. In our case it generally gets left in as DEBUG code by mistake. Developers could use it as a place holder which looks like the case in your example.
People use 1=2 to check if their code is syntactically correct without the code performing anything. For example if you have a complicated UPDATE statement and you want to check if the code is correct without updating anything.