CASE WHEN in request - sql

I have a "user_activity_log" table that contains the fields "id", "client_id", "hitdatetime", and "action".
id
client_id
hitdatetime
action
2661715
17
2020-09-18 11:30:43
visit
2661716
17
2020-09-18 11:30:54
registration
2661717
17
2020-09-18 11:31:16
visit
It is necessary to output:
"client_id", from the input table
"visit_dt", that is associated to the "hitdatetime" field when the "action" equals to 'visit', otherwise it is null
"is_registration", that is associated to 1 if "action" equals to 'registration', otherwise it is 0
The CASE statement is mandatory for this query.
I've started writing the query, but I don't know what to put in place of the signs ???.
SELECT client_id,
CASE WHEN action = 'visit' THEN ??? ELSE 'NULL' END as visit_dt,
CASE WHEN action = 'registration' THEN '1' ELSE '0' END as is_registration
FROM user_activity_log;
Can you provide help?

Try with the following one:
SELECT client_id,
CASE WHEN action = 'visit'
THEN hitdatetime END AS visit_dt,
CASE WHEN action = 'registration'
THEN 1
ELSE 0 END AS is_registration
FROM user_activity_log;
Side notes:
if the ELSE clause of the CASE statement should evaluate to NULL, you are not required to specify it as it is default value
use numeric values in place of strings if the nature of your input should be numeric
always prefer using NULL instead of the corresponding "NULL" string, as sql provides a whole set of functions that can handle NULL values in a better way

is_registration should really be boolean. Also makes the query simpler:
SELECT client_id
, CASE WHEN action = 'visit' THEN hitdatetime END AS visit_dt
, action = 'registration' AS is_registration -- !
FROM user_activity_log;
If action can be NULL, so can be is_registration. If you want false instead of null, use one of these:
action IS NOT DISTINCT FROM 'registration' AS is_registration
Or:
COALESCE(action = 'registration', false) AS is_registration
Related:
Change varchar to boolean in PostgreSQL
Why does PostgreSQL not return null values when the condition is <> true
Best way to check for "empty or null value"

Related

Turn OFF/ON condition related on variable

I have variable ,#UseClarifiedChangeType INT = ISNULL(CAST([Config].[fn_Configuration_Get]('LCSP_ExecChanges_UseClarifiedChangeType') AS INT), 0)
And in middle of sql I have condition AND ISNULL(CHT.ClarifiedChangeType, ECH.ChangeType) IN ('Joining', 'Promotion', 'Internal Move')
I need to use it only if #UseClarifiedChangeType is 1
How I can do this?
Negate the boolean
AND (
#UseClarifiedChangeType != 1
OR ISNULL(CHT.ClarifiedChangeType, ECH.ChangeType) IN ('Joining', 'Promotion', 'Internal Move')
)
This test will pass if either
#UseClarifiedChangeType is 1 and your ISNULL(...) part is true
#UseClarifiedChangeType is something other than 1 (in which case the IsNULL(...) part is never run)

How to add conditional statement inside SQL query?

Hi I am working on one SQL query. Below is my method name which executes query.
private string GetAggregatedOptionParametersByStyleIdCommand(string styleId, bool currentStore)
{
SELECT
opts.style, opts.option::text as {OptionKey}, opts.primary_colour, opts.secondary_colour, opts.brand_description, opts.description, params.*,
CASE WHEN {currentStore} == true THEN
FROM
rex.options opts
JOIN
rex.product_atoms atoms ON atoms.option_id = opts.option
JOIN
rex.parameters params ON atoms.id = params.product_atom_id
JOIN
rex.stores stores ON params.store = stores.id
WHERE
opts.style = '{styleId}'
}
Below is the structure of stores table.
CREATE TABLE rex.stores (
id serial NOT NULL,
close_date timestamp NOT NULL,
country text NULL,
distribution_centre text NULL,
"name" text NULL,
open_date timestamp NOT NULL,
CONSTRAINT "PK_stores" PRIMARY KEY (id)
);
So what I am trying to make is, Whenever the currentStore is true then I want to return the current store. Condition to check currentStore is
store.OpenDate <= currentDate &&
store.CloseDate >= currentDate
Whenever the currentStore is false I want to return all store. To check all store condition is
store.CloseDate >= currentDate
I am trying to add these conditions inside SQL query. I have added CASE WHEN {currentStore} == true THEN I am not sure how to add my closed store condition. Can anyone help me to complete this query? Any help would be appreciated. Thank you.
If you want to check for another possibility you can either add another WHEN or ELSE condition to your CASE statement. These need to come before the END.
For example:
CASE
WHEN x < 0 THEN 'negative'
WHEN x > 0 THEN 'positive'
ELSE 'zero'
END
I am not familiar with postgres, you may not need an END, and you may also be able to say CASE x WHEN > 0 THEN... WHEN < 0 ... meaning you only need to mention x once after CASE; again, this may not be a thing in postgres.

how to prevent converting the text into boolean by the use of when statement in postgresql?

select fti.pa_serial_,fti.homeownerm_name,fti.ward_,fti.villagetole,fti.status,
ftrq.date_reporting, ftrq.name_of_recorder_reporting,
case
when fti.status='terminate' then ftrq.is_the_site_cleared ='1' end as is_the_site_cleared from fti join ftrq on ftrq.fulcrum_parent_id = fti.fulcrum_id
Here, is_the_site_cleared is text type of column which is converted into boolean by the when statement written and hence does not print as 1 and takes as true. I explicitly used print '1'. But this also did not work. My aim is to display '1' in the column 'is_the_site_cleared' when the value of fti.status='terminate'. Please help!!!
How about using integers rather than booleans?
select fti.pa_serial_, fti.homeownerm_name, fti.ward_,
fti.villagetole, fti.status, ftrq.date_reporting,
ftrq.name_of_recorder_reporting,
(case when fti.status = 'terminate' -- and ftrq.is_the_site_cleared = '1'
then 1 else 0
end) as is_the_site_cleared
from fti join
ftrq
on ftrq.fulcrum_parent_id = fti.fulcrum_id ;
From the description, I cannot tell if you want to include the condition ftrq.is_the_site_cleared = '1' in the when condition. But the idea is to have the then and else return numbers if that is what you want to see.

Why 'NOT IN' operator not fetching records for the columns which is not having any value?

I have a table with a column name CORP_SERIOUS,the values of this column can be 1 or 2 or empty. When I am searching unknown values records means empty field using NOT IN operator i am getting the count is zero.
Why the below query is not fetching the records for the field which doesn't have vm.CORP_SERIOUS NOT IN('1','2')?
Here is the Query:
SELECT COUNT(*)
FROM
( SELECT DISTINCT vm.vaer_no vaer,
vm.vaer_no_version version,
vm.priority priority,
vm.case_reported_in reportedIn,
vsr.originalreceivedate initialRcvDate,
vsr.mostrecentinfodate latestRcvDate,
vsr.primarysourcecountry reportingCountry,
vsr.occurcountry occurCountry,
vsrd.primary_source_full_name reporterFullName,
vsrd.sender_full_name senderFullName,
vm.record_id recordId,
vm.notes_flag notesFlag,
vm.dmi_product product,
vmf.VAERS_LINKED,
vm.VAER_STATUS status,
vm.company_unit_name companyunit,
FIND_WF_ACTIVITY(vm.record_id,JBPM_PROCESS_INST_ID),
vmf.CORRESPONDENCE_FLAG corresFlag,
vmf.READ_UNREAD_CORRESPONDENCE readUnreadCorresp,
vm.vaer_mode vmode,
srcDoc.doc_name,
vsr.seriousnessdecision serious,
vm.reportduedate reportduedate,
vm.MANUALLY_LOCKED,
vm.LOCKED_BY,
vm.LOCKED_REASON,
vm.LOCKED_DATE,
vm.vaer_delete,
vm.vaer_nullify nullify,
vm.archived,
vm.COMPLETION_FLAG,
vm.ASSIGNED_USER_GROUP,
COALESCE(vsrd.TEEATESPECIESDECODE,vsrd.SPECIESDECODE,vsrd.OTHERSPECIES,vsrd.TREATEDSPECIES),
COALESCE(vsrd.ANIMAL_BREEDDECODE,vsrd.TREATED_BREEDDECODE,vsrd.ANIMAL_BREED,vsrd.TREATED_BREED),
vm.APPROVED_VAER,
vm.SUBSTANCE_ADDED,
vm.MULTIPLEBREEDADDED,
msg_q.MDN_DATE,
vm.CASE_SOURCE,
vm.MESSAGENUMB,
vsr.NULLIFICATIONREASON,
vm.CREATED_BY,
vm.ASSESSMENT_SOURCE,
vm.ASSESSMENT_CLASSIFICATION,
vm.DMI_VEDDRA_TERM,
vsr.CASEREGISTRATIONTYPE,
vm.AUTHORIZATIONCOMPANY,
vm.E2B_DMI_PRODUCT brandname,
vm.E2B_SUBSTANCE_ADDED e2bSubstanceAdded,
vm.ACCOUNT account,
ACK.record_id ack_recId ,
vm.SUBMITTED_DELAY
FROM agvet_vae_info vm,
agvet_vae_safetyreport vsr,
agvet_vae_safetyreport_detail vsrd,
AGVET_VAE_SOURCE_DOC srcDoc,
AGVET_VAE_FLAGS vmf,
E2B_MESSAGE_QUEUE msg_q,
E2B_MESSAGE_ACK ACK
WHERE vm.fk_avsr_rec_id = vsr.record_id
AND vsr.fk_avsrd_rec_id = vsrd.record_id
AND srcdoc.record_id(+) = vm.fk_vet_source_doc_rec_id
AND vm.IMPORT_FLAG <> 1
AND (vm.DRAFT_SUBMIT_FLAG = 0
OR vm.DRAFT_SUBMIT_FLAG = 2)
AND vm.VAER_NO = vmf.VAER_NO(+)
AND vm.E2B_MESSAGE_LIST_TYPE<>01
AND vm.MESSAGENUMB = msg_q.MESSAGE_NUMBER(+)
AND vm.MESSAGENUMB = ACK.MESSAGE_NUMBER(+)
AND (vm.assigned_to = 48626
OR vm.assigned_to IS NULL
OR vm.assigned_to = 320538
OR vm.assigned_to = 320529
OR vm.assigned_to = 406699)
AND EXISTS
(SELECT *
FROM jbpm_token jt
WHERE jt.node_ IN ( 135,140,146,137,132,129,127,148,144 )
AND jt.processinstance_ = vm.jbpm_process_inst_id
OR vm.jbpm_process_inst_id IS NULL
)
AND ( fn_access_vet_products(48658,vm.RECORD_ID, vm.CASE_REPORTED_IN)=1)
AND (vm.PRIORITY IN ( 02 )
OR vm.PRIORITY IS NULL)
AND ( upper(vm.CORP_SERIOUS) NOT IN ('1','2') )
AND vm.ARCHIVED = 0
AND vm.vaer_nullify = 0
AND vm.vaer_delete = 0
)
The value NULL means unknown.
WHERE vm.CORP_SERIOUS IN('1','2')
is TRUE for '1'
is FALSE for '3'
is NULL for NULL
And
WHERE vm.CORP_SERIOUS NOT IN('1','2')
is NOT TRUE, hence FALSE for '1'
is NOT FALSE hence TRUE for '3'
is NOT NULL, which is again NULL for NULL
As NULL means unknown, we don't know whether the value (that we don't know) is in the given set or not. So the answer is "I don't know", no matter if we ask whether the value is in the list or whether the value is not in the list.
Imagine we don't know John's phone number and I show you some numbers and ask you whether John's number is among them. You can't say yes, you can't say no, you can only say maybe. Same with the DBMS. It cannot tell you TRUE or FALSE, it can only tell you NULL. Now the WHERE clause works like this: The query returns all records for which the given criteria is TRUE. NULL is not TRUE, so the records are not returned.
(Even if NULL itself were in the list, we wouldn't know whether the unknown value in the set is the same as the unknown value in the record. The WHERE clause would still result in NULL. It would make a difference for '3' though: WHERE vm.CORP_SERIOUS NOT IN('1','2', null) would suddenly result in NULL too, because the unknown value in the set could or could not be '3'.)
You could ask: Give me all unknown values plus the values in the list.
WHERE vm.CORP_SERIOUS IS NULL OR vm.CORP_SERIOUS NOT IN('1','2')
Or you could ask:
WHERE NVL(vm.CORP_SERIOUS, 'TREAT AS NOT IN THE LIST') NOT IN('1','2')
(Well, of course the string 'TREAT AS NOT IN THE LIST' must not be in the list then :-)
You can try this query
convert(varchar(50),vm.CORP_SERIOUS) NOT IN('1','2')

Search Query to Filter Out records from Database

I am entering some values on a search engine on GUI
Name, Date, State
If a user does not enter any value, and click on 'Search', he should get entire table from the database. i.e. no filters are applied.
So for example i wrote
Select Name, State, Date from Table where Name='' and State= '' and Date= ''
But if i enter no values in GUI, no records are fetched from DB. But i want these to act as filters and not conditions.
I am using DB2
Please suggest me the correct way. Thank you.
Try this
SELECT Name, State, Date
FROM
Table
WHERE
CASE WHEN ISNULL(#Name,0)=0 THEN 0 ELSE Name END = ISNULL(#Name,0)
AND
CASE WHEN ISNULL(#State,0)=0 THEN 0 ELSE State END = ISNULL(#State,0)
AND
CASE WHEN ISNULL(#Date,0)=0 THEN 0 ELSE Date END = ISNULL(#Date,0)
The following query would be correct for this purpose,
Select Name, State, Date
from Table
where (:Name_Var is null OR Name = :Name_Var AND
(:State_Var is null OR State =:State_Var) AND
(:Date_Var is null OR Date = :Date_Var)