How to add conditions for blank prompts in PSQuery? - sql

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.

Related

Option to leave part of a searchable report/form blank in Microsoft access

I have a query in MS Access that is linked to a searchable report which is linked to a form. Part of the report ask users to include two reasons that will be used as criteria for a query. Currently, the report (screenshot) below does not allow for users to simply enter in 1 reason. Users must enter in 2 reasons, and if the reasons are the same, users must enter in the same reason for both fields. For example, If I only have one reason (conflict of Interest),I would need to enter that reason into both reason boxes shown on the screenshot below. I would like to be able to search for one reason while also being able to leave the other reason box blank. So simply entering in Conflict of interest for one box and have it run the query. The code I have for the query is below.
SELECT C1.ConsultID, C1.Consult_No, C1.Consult_Type, C1.Intake_Date, C1.Adult_Peds, C1.Title, C1.ConsultSummary
FROM ([Intersection Query Pre-Reasons] AS C1 LEFT JOIN tblConsultReasons AS C2 ON C1.ConsultID = C2.ConsultID) LEFT JOIN tblConsultReasons AS C3 ON C2.ConsultID = C3.ConsultID
WHERE (((C2.Reason)=Forms!FrmReasonsCriteria!Reason1) And ((C2.ReasonType)="Discerned")) And (C3.Reason)=Forms!FrmReasonsCriteria!Reason2 And C3.ReasonType="Discerned";
How would you recommend I change the code in order to do this. I believe adding a length condition to the second half of the where clause may work. But am not sure what this would look like.
Screenshot of part of the searchable report that queries on reasons
It will be something like this; I haven't tested it because that requires building forms etc and I don't have the time atm:
SELECT C1.ConsultID, C1.Consult_No, C1.Consult_Type, C1.Intake_Date, C1.Adult_Peds, C1.Title, C1.ConsultSummary
FROM ([Intersection Query Pre-Reasons] AS C1
LEFT JOIN tblConsultReasons AS C2 ON C1.ConsultID = C2.ConsultID)
LEFT JOIN tblConsultReasons AS C3 ON C1.ConsultID = C3.ConsultID
WHERE
NOT (nz(Forms!FrmReasonsCriteria!Reason1,'')='' And
nz(Forms!FrmReasonsCriteria!Reason2,'')=''
)
And (
(nz(C2.Reason=Forms!FrmReasonsCriteria!Reason1,'')=''
And C2.ConsultID is null)
Or
(nz(C2.Reason=Forms!FrmReasonsCriteria!Reason1,'')<>'' And
C2.Reason=Forms!FrmReasonsCriteria!Reason1 And
C2.ReasonType="Discerned")
)
And (
(nz(C3.Reason=Forms!FrmReasonsCriteria!Reason2,'')=''
And C3.ConsultID is null)
Or
(nz(C3.Reason=Forms!FrmReasonsCriteria!Reason2,'')<>'' And
C3.Reason=Forms!FrmReasonsCriteria!Reason2 And
C3.ReasonType="Discerned")
)
It can be simplified a bit if we know the data available, and other controls/checks the search boxes may have.

SQL WHERE filter

I suck at explaining this issue, but I hope someone understands.
How do I filter something out of a column if it meets just one criteria out of the whole value?
So in this example I want to filter out any value that includes "First Touch", even if the value has other SpecialNeedsTagNames as well. For example "First Touch, Do Not Contact, Self-Serve Pilot" etc..
SELECT count(*) AS count
FROM
(select *
from OperationalReporting.VW_Delivery
WHERE DeliveryCountry in ('NO',
'FI',
'DK',
'SE',
'IS')) AS expr_qry
WHERE "CountryOfUse" = 'Sweden'
AND "OrderStatus" IN ('Booked',
'Order Placed')
AND "IsDelivered" = 'false'
AND "Model" NOT IN ('Model QW',
'Model PX',
'Model ZY')
AND ((SalesAdvisorHomeStore like 'EU-SE%'
OR CommisionabaleStore like 'EU-SE%')
AND (SpecialNeedsTagName is null
or (SpecialNeedsTagName not like '%First Touch%')))
ORDER BY count DESC
LIMIT 50000;
Currently it only filters out the values that ONLY have "First Touch", as soon as it has a combined value it still outputs in the column.Faulty values
So first things first, you may want to unify all values in you column by giving UPPER or LOWER. The where statement would look like this:
WHERE UPPER(SpecialNeedsTagName) LIKE 'FIRST TOUCH%'
If you want to make sure that there are no nulls add AND IS NOT NULL.
This where will return you all of results that starts with FIRST TOUCH. If you are expecting that this phrase may occure in the middle of string add % at the beginning ('%FIRST TOUCH%')
Try This :
SELECT count(*) AS count
FROM
(select *
from XX.XX_XX
WHERE NOT EXISTS (select * from XX.XX_XX where UPPER(SpecialNeedsTagName)
LIKE '%First Touch%'))
ORDER BY count DESC
LIMIT 50000;

SQL Update based on secondary table in BQ

I have 2 tables, 1 containing the main body of information, the second contains information on country naming convensions. in the information table, countries are identified by Name, I would like to update this string to contain an ISO alpha 3 value which is contained in the naming convention table. e.g turning "United Kingdom" -> "GBR"
I have wrote the following query to make the update, but it effects 0 rows
UPDATE
`db.catagory.test_votes_ds`
SET
`db.catagory.test_votes_ds`.country = `db.catagory.ISO-Alpha`.Alpha_3_code
FROM
`db.catagory.ISO-Alpha`
WHERE
`LOWER(db.catagory.ISO-Alpha`.Country) = LOWER(`db.catagory.test_votes_ds`.country)
I've done an inner join outside of the update between the 2 to make sure that the values are compatable and it returns the correct value, any ideas as to why it isn't updating?
The join used to validate the result is listed below, along with the result:
SELECT
`db.catagory.test_votes_ds`.country, `db.catagory.ISO-Alpha`.Alpha_3_code
from
`db.catagory.test_votes_ds`
inner join
`db.catagory.ISO-Alpha`
on
LOWER(`db.catagory.test_votes_ds`.country) = LOWER(`db.catagory.ISO-Alpha`.Country)
1,Ireland,IRL
2,Australia,AUS
3,United States,USA
4,United Kingdom,GBR
This is not exactly an answer. But your test may not be sufficient. You need to check where the values do not match. So, to return those:
select tv.*
from `db.catagory.test_votes_ds` tv left join
`db.catagory.ISO-Alpha` a
on LOWER(tv.country) = LOWER(a.Country)
where a.Country IS NULL;
I suspect that you will find countries that do not match. So when you run the update, the matches are getting changed the first time. Then the non-matches are never changed.

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')

complex MySQL Order by not working

Here is the select statement I'm using. The problem happens with the sorting. When it is like below, it only sorts by t2.userdb_user_first_name, doesn't matter if I put that first or second. When I remove that, it sorts just fine by the displayorder field value pair. So I know that part is working, but somehow the combination of the two causes the first_name to override it. What I want is for the records to be sorted by displayorder first, and then first_name within that.
SELECT t1.userdb_id
FROM default_en_userdbelements as t1
INNER JOIN default_en_userdb AS t2 ON t1.userdb_id = t2.userdb_id
WHERE t1.userdbelements_field_name = 'newproject'
AND t1.userdbelements_field_value = 'no'
AND t2.userdb_user_first_name!='Default'
ORDER BY
(t1.userdbelements_field_name = 'displayorder' AND t1.userdbelements_field_value),
t2.userdb_user_first_name;
Edit: here is what I want to accomplish. I want to list the users (that are not new projects) from the userdb table, along with the details about the users that is stored in userdbelements. And I want that to be sorted first by userdbelements.displayorder, then by userdb.first_name. I hope that makes sense? Thanks for the really quick help!
Edit: Sorry for disappearing, here is some sample data
userdbelements
userdbelements_id userdbelements_field_name userdbelements_field_value userdb_id
647 heat 1
648 displayorder 1 - Sponsored 1
645 condofees 1
userdb
userdb_id userdb_user_name userdb_emailaddress userdb_user_first_name userdb_user_last_name
10 harbourlights info#harbourlightscondosminium.ca Harbourlights 1237 Northshore Blvd, Burlington
11 harbourview info#harbourviewcondominium.ca Harbourview 415 Locust Street, Burlington
12 thebalmoral info#thebalmoralcondominium.ca The Balmoral 2075 & 2085 Amherst Heights Drive, Burlington
You are trying to use an invalid ORDER BY.
ORDER BY (t1.userdbelements_field_name = 'displayorder' AND t1.userdbelements_field_value)
It must reference a table column or returned aliased column.
I really cannot follow how this query would even be possible as you already have limited
t1.userdbelements_field_name = newproject and then you wish to order by the case of it being equal to displayorder.
Could you please modify your question to state exactly what it is that you are trying to accomplish in your order by clause?
From what I understand, you'd have to join to default_en_userdbelements solely for the displayorder value. However, I suspect there's something wrong with your query and that it probably returns duplicate values for userdb_id.
Perhaps you should say what you're trying to actually do, not explain the way you're trying to do it.
SELECT t1.userdb_id
FROM default_en_userdbelements AS t1
JOIN default_en_userdb AS t2 ON t1.userdb_id = t2.userdb_id
JOIN default_en_userdbelements AS o ON (o.userdb_id, o.userdbelements_field_name)
= (t1.userdb_id, 'displayorder')
WHERE t1.userdbelements_field_name = 'newproject'
AND t1.userdbelements_field_value = 'no'
AND t2.userdb_user_first_name != 'Default'
ORDER BY o.userdbelements_field_value,
t2.userdb_user_first_name
You could do something like this:
ORDER BY
(CASE WHEN t1.userdbelements_field_name = 'displayorder'
THEN t1.userdbelements_field_value
ELSE $some_large_number
END),
t2.userdb_user_first_name;
It sorts using the value of t1.userdbelements_field_value when t1.userdbelements_field_name = 'displayorder', but you have to supply some other value of the same type to apply for the ELSE.