Cypher: Can we put if...else in where condition? - cypher

I am going to do a search. I have to put different condition for different person type. Could anybody tell me how to do this in Cypher? Cheers.
START ...
MATCH ...
WHERE
if person.type! ='Teacher'
...//add condition
else if person.type! ='Student'
...//add condition
else if person.type!='Assistant'
...//add condition
else
...//add condition
Return ...

It's a little difficult to give you a complete answer without understanding what your // add condition should be doing.
However, I suspect that what you are looking for is CASE.
An example which may meet your requirements is something like this
MATCH (person:Person{name: "John"})
SET person.salary =
CASE person.type
WHEN 'Teacher' THEN 50000
WHEN 'Assistant' THEN 40000
WHEN 'Student' THEN 0
ELSE NULL
END
RETURN person

Related

Ignore clauses in where based on if you get a result from the select

I want the following sql statement to give me different results based on whether it finds a result within the specific string or it needs to search the whole parent group (so within the table there are for example:
column 1, column 2
a - 1
a - 2
a - 3
b - 5
b - 7
b - 1
so if it can find the result if i put 1 it will display me
a -1
b -1
. the problem is that in the where clause exist both the parent group and the child group
i have tried to use case and also to simulate an if with ands and ors but it didn't work
select 1,
aapv.aapv_keyext1,
aapv.aapv_area,
aapv.aapv_valuecharmax,
aapv.aapv_valuechardefault,
aapv.aapv_valuecharmin, aap.aap_ident
from a_parameter_value aapv,
a_parameter aap
where aap.aap_ident in (string1,string2,string3)
and aap.aap_ref = aapv.aap_ref
and aap.aap_idento = string4
and ((aapv.Aapv_Keyext1 = 'LaD1' --child clause
and aapv.aapv_keyext1 is not null)
or aapv.Aapv_Area = 'LSDe' --parent clause
and aapv.Aapv_Area is null)
I expect the output to be if the aapv_keyext1 value finds any results then the appv_area is not used at all but either only the child clause is used with the above code or both if i remove the is null clause
Okay, you need to provide more information for us to give you a real answer, but I wanted to point out that this section has some logic problems:
and ((aapv.Aapv_Keyext1 = 'LaD1' --child clause
and aapv.aapv_keyext1 is not null)
or aapv.Aapv_Area = 'LSDe' --parent clause
and aapv.Aapv_Area is null)
The first part is saying aapv_keyext1 = 'LaD1' AND aapv_keyext1 is not null; the second half can never be false, so it's redundant. The second part is saying aapv_area = 'LSDe' AND aapv_area is null. This will never be true. So this whole section is equivalent to:
and (aapv.aapv_keyext1 = 'LaD1')
Which probably isn't what you want. You say you want "if the aapv_keyext1 value finds any results then the appv_area is not used at all". I suspect what you mean is that "if any results exist for aapv_keyext1 in any rows then don't use aapv_area" which is more complicated, you need a subquery (or analytic/aggregate functions) to look at what other rows are doing.
select 1,
aapv.aapv_keyext1,
aapv.aapv_area,
aapv.aapv_valuecharmax,
aapv.aapv_valuechardefault,
aapv.aapv_valuecharmin, aap.aap_ident
from a_parameter_value aapv,
a_parameter aap
where aap.aap_ident in (string1,string2,string3)
and aap.aap_ref = aapv.aap_ref
and aap.aap_idento = string4
and (-- prefer keyext1
aapv.Aapv_Keyext1 = 'LaD1'
OR
-- if keyext1 doesn't find results...
(NOT EXISTS (select 1 from a_parameter_value aapv2
where aapv2.aap_ident = aap.aap_ident
and aap2.aap_ref = aap.aap_ref
and aap2.aap_idento = aap.aap_idento
and aapv.Aapv_Keyext1 = 'LaD1')
AND
-- ... use aapv_area
aapv.Aapv_Area = 'LSDe')
);
You can also do this kind of conditional logic with CASE statements, but you're still going to need a subquery or something if you want your logic to depend on the values in rows other than the one currently being looked at.
Let me know if I've misunderstood your question and I'll try to update with a better answer.

How to add conditions for blank prompts in PSQuery?

I need help with myPS Query. This is how it goes below:
SELECT A.EMPLID, B.STUDENT_ID, C.ADMIT_TERM, D.CHECKLIST_CD,
D.CHECKLIST_STATUS...
FROM TABLE1 A, TABLE2 B, TABLE3C, TABLE4 D...
WHERE……
AND A.EMPLID = :1
AND C.ADMIT_TERM = :2
AND D.CHECKLIST_CD = :3
AND D.CHECKLIST_STATUS = :4
….
Now there are certain conditions wherein prompts 1,2,3 and 4 are not provided that conditions below should happen:
All students with incomplete / in progress checklists will be shown regardless of when they were created.
All students whose checklists were completed within the current Term will be shown.
At this point, I don't know how to add a condition if all those prompts are blank. Can you advise what I need to do next? Sub-queries? Expression?
Help please.
This is basically the same as Littlefoot's answer, but I'll try to add some more detail about how to accomplish that solution. This is an example of a query I did which is similar to what you're trying to do, with a little tweak added on the ORDER_NO field to demonstrate what you're trying to do. I don't know how to make it return certain rows only if all prompts are not provided, but this will let you return certain rows for each specific prompt which isn't provided. For example, if you don't provide a checklist status, then you can return all students that are in incomplete and in progress status.
Note that this is a very old version of PeopleSoft, so your interface is probably different.
First, add your prompts
Now, the trick is to make the WHERE clause for each optional field work like WHERE (D.CHECKLIST_STATUS = :4 OR (:4 = '' AND D.CHECKLIST_STATUS IN ('I', 'P')) (or whatever your status codes are). Here's how to do that (again, on my old version). The logic on the ORDER_NO field is similar to what you'll need.
Make sure to set your AND/OR operators and your parenthesis appropriately.
Clicking on the Edit button for the '' equal to :2 criteria, this is what it looks like
And the SQL looks like this
Now when you run the query, any of the prompt fields that you leave empty will either not be used to filter the results, or the default values for that field will be used.
In Oracle, it is usually handled as follows:
select ...
from ...
where (a.emplid = :1 or :1 is null)
and (c.admint_term = :2 or :2 is null)
...
Use LIKE instead of = operator. For instance
SELECT A.EMPLID, B.STUDENT_ID
FROM TABLE1 A
WHERE
AND A.EMPLID LIKE :1
if you want to select all the employees then pass % in :1 parameter.

Applying the count function within the case function

I am relatively new to SQL and am trying to apply the case function within a view.
While I understand the fundamentals of it, I am having difficulty applying it in the way that I need.
I have 3 columns ApplicationID, ServerName and ServerShared? (true/false).
Each application can have many servers associated to it, while each server only has 1 server type.
I would like to use case to create a further field which can take three values dependent upon whether the values of ServerShared related to an application are all True = Shared, False = Non-shared, Both True and False = Partially shared.
My thoughts were using count function within the case function to set statements where:
if 'count true > 0 and count false > 0' then ServerShared? =
partially if 'count true > 0' and 'count false = 0' then
ServerShared = true and vice versa.
I believe the above logic a way of achieving my result, yet I would appreciate help in both how to structure this within a case statement and any wisdom if there is a better way.
Thanks in advance!
If I get your question right, this should do the trick. Maybe you need to add further columns or adapt the logic. But you should get the logic behind.
SELECT ServerName,
CASE
WHEN COUNT(distinct ServerShared) = 2
THEN N'Server shared'
WHEN MIN(ServerShared) = 0
THEN N'Server not shared'
WHEN MAX(ServerShared) = 1
THEN N'Server shared'
END as ServerShared
FROM myTable
GROUP BY ServerName
There are two main ways to do this problem (super generic answer from non expert :D)
less often executed (one off?), slow execution with potential exponential time increases as rows go up:
This is similar to your suggested solution and involves putting other queries in the Select / field list part of the query - this will get executed for every row returned by the main part of the query (bad news generally speaking):
select
applicationID
, Case (select count * from table as b where a.applicationid = b.applicationid and shareserver=true)
WHEN 0 then 'Non-Shared'
WHEN (select count * from table where a.applicationid = b.applicationid) then 'Shared'
ELSE 'Partially-Shared' END as ShareType
from
tabls as a
get all your data once then perform just the comparison row by row. this is what i would use by default.. its basically better as far as i know but sometimes can be harder to think through.
this line is here to fix formatting issue
select
a.applicationid
,case
when sharedservers = 0 then 'Non-Shared'
when totalservers=sharedservers then 'Shared'
else 'Partially-Shared' END as ShareType
FROM
(select applicationID, count(*) as TotalServers from table) as a
LEFT OUTER JOIN (select applicationID, count(*) as SharedServersfrom table where sharedserver = true) as b
ON a.applicationid=b.applicationid
these queries are just written off the top of my head let me know if there are bug :/
note also the two uses of case statement. one with CASE *value* WHEN *possible value* THEN .. and the second way CASE WHEN *statement that evaluates to boolean* THEN ..

How to see if some condition is met, and based on that to display result

I have database(university) in which I need to see if two lectures have the same teacher, or not, and based on that I need to display answer("yes" && "no").
My question is, how can I display it? I always thought that I can put only colum names?
Before posting this question, I looked at google to se if there is anyting helpful there, and the only thing I found was the case statment, which was not too helpful, becuse I am always getting error messages when calling some function(exists, ...).
You could use a case statement:
select case
when l1.Teacher = l2.Teacher then 'yes'
else 'no'
end
from lectures l1
cross join
lectures l2
where l1.name = 'Quantum Mechanics'
and l2.name = 'Buddhism II'

Oracle SQL - Left join on "in" statements

The point of the query below is to return a list of people and whether or not they are unhappy. But, If I don't know if they are happy or not, I want to list their name and their unhappy as "happy". This is complicated by the fact that I have some additional requirements for what defines unhappy.
I'm writing a query like this...
Select name.firstName,
CASE
WHEN Mood.mood is not null
THEN 'Unhappy'
ELSE 'Happy'
END Unhappy
From name
Mood
WHERE mood.firstName(+) = name.firstName
AND mood.type IN ('Hungry','Tired','Fatigued','Bored',null)
AND mood.value(+) > 5;
So I want to return every single name from the table name, and either a value of "happy" or "unhappy", even though those names may or may not be in mood table. When I run this as I've written it, I get no rows. I figure this might involve my mood.type line because I can't use a left join on an "in" statement.
I think you have a couple of problems:
You have a spurious semi-colon in your WHERE clause.
The CASE expression is in the wrong place.
You shouldn't use NULL in an IN expression.
You could remove the semi-colon and change your IN expression to this instead:
AND (mood.type IN ('Hungry','Tired','Fatigued','Bored') OR mood.type IS NULL)
Also, I'd strongly advise you not to use that obsolete join syntax. It's probably a good idea to use the JOIN keyword as it makes this sort of query a lot easier.
SELECT
name.firstName,
CASE
WHEN Mood.mood IS NOT NULL
THEN 'Unhappy'
ELSE 'Happy'
END Unhappy
FROM name
LEFT JOIN Mood ON
mood.firstName = name.firstName AND
mood.type IN ('Hungry','Tired','Fatigued','Bored') AND
mood.value > 5
I would do it like this:
select n.firstname,
nvl(m.mood, 'Happy') mood
from
name n
left outer join mood m
on n.firstname = m.firstname
where
nvl(m.type,'Hungry') in ('Hungry', 'Tired', 'Fatigued', 'Bored')