Case when condition is Where clause SQL Server 2017 - sql

I'm trying to a use a CASE expression in the WHERE clause in SQL. I don't know how I to put it in.
For example:
select id , name = case when first_name = 'a' then 'NA' else null end
from MyTable
where case when first_name = 'a' then 'NA' else null end is null
I want to show results when they are null. How can I do that please?

Based on your query here is query that should work.
SELECT
[id]
,CASE [first_name] WHEN 'a' THEN 'NA' ELSE NULL END AS 'name'
FROM [MyTabl]
WHERE 1 = CASE [first_name] WHEN 'a' THEN 0 ELSE 1 END
You can use the case to return a string or numeric and then just say where equal to that value. Warning this can be quite slow and it is better to use an where statement.
This would be better as a select statement :
SELECT
[id]
,CASE [first_name] WHEN 'a' THEN 'NA' ELSE NULL END AS 'name'
FROM [MyTabl]
WHERE [first_name] <> 'a'
Alternative query :
SELECT
[id]
,CASE [first_name] WHEN 'a' THEN 'NA' ELSE NULL END AS 'name'
FROM [MyTabl]
WHERE [id] NOT IN ( SELECT [id] WHERE [first_name] = 'a' )

Related

Convert data type to text for case statement

I need to convert data type to text for following statement. Can someone please help…
CASE WHEN [OrderID] IS NULL THEN 'N'
WHEN [Order_ID] = '' THEN 'N'
ELSE [Order_ID] END AS [Order_ID]
Try casting the order ID to varchar in the ELSE branch of your CASE expression:
CASE WHEN COALESCE([Order_ID], '') = ''
THEN 'N'
ELSE CAST([Order_ID] AS VARCHAR(MAX)) END AS [Order_ID]
consider isnull()
CASE WHEN isnull([OrderID], '') = '' THEN 'N'
ELSE cast([Order_ID] as varchar(300)) END AS [Order_ID]
You Can try below also :
CASE WHEN OrderID IS NULL THEN 'N'
WHEN OrderID ='' THEN 'N'
ELSE convert(varchar(20),OrderID ) END
Try this Alternate Method-
IIF(ISNULL([OrderID],'')='','N',CAST([OrderID] AS NVARCHAR(MAX))) AS [OrderID]

ADD Constraints in value of column based on another value in other column

I'm writing an sql constraints about values on columns based on other values in other columns for Example:
if Column Replacement Part = 'N/A', the Replacement Company must be = 'N/A' and verse vice .
if type ='obs' the LTB_Date and LTS_Date Must be Not Null and
if type !='obs' the LTB_Date and LTS_Date Must be Null
Try to use a CHECK constraint like this:
ALTER TABLE PCN_Table ADD CONSTRAINT CHECK(
CASE
WHEN Replacement_Part = 'N/A' THEN CASE WHEN Replacement_Company = 'N/A' THEN 1 ELSE 0 END
ELSE 1
END=1
AND
CASE
WHEN [type] = 'obs' AND LTB_Date IS NOT NULL AND LTS_Date IS NOT NULL THEN 1
WHEN [type] <> 'obs' AND LTB_Date IS NULL AND LTS_Date IS NULL THEN 1
ELSE 0
END=1
)

Optimizing a Postgres query

I have following query
SELECT
ca.sfid,
CASE WHEN p.Name IS NOT NULL THEN p.Name ELSE '' END AS Property,
CASE WHEN uc.Name IS NOT NULL THEN uc.Name ELSE '' END AS UnitofInterest,
CASE WHEN fp.Name IS NOT NULL THEN fp.Name ELSE '' END AS FloorplanofInterest,
CASE WHEN ca.Status IS NOT NULL THEN ca.Status ELSE '' END AS Status,
CASE WHEN ca.Origin IS NOT NULL THEN ca.Origin ELSE '' END AS Origin,
CASE
WHEN ca.IC_Call_Answered_by_AH__c = 'true' THEN 'Anyone Home'
ELSE 'Property'
END AS AnswerBy,
CASE WHEN ca.CaseNumber IS NOT NULL THEN ca.CaseNumber ELSE '' END AS CaseNumber,
CASE WHEN ca.Ad_Source_Type__c IS NOT NULL THEN ca.Ad_Source_Type__c ELSE '' END AS Source,
CONCAT(c.FirstName,' ',c.LastName) AS contactname,
CASE WHEN (c.Phone IS NOT NULL OR c.Phone != '' ) THEN c.Phone ELSE '' END AS Phone,
CASE WHEN c.MobilePhone IS NOT NULL THEN c.MobilePhone ELSE '' END AS Mobile,
CASE WHEN c.Email IS NOT NULL THEN c.Email ELSE '' END AS Email,
CASE WHEN c.most_recent_military_pay_grade__c IS NOT NULL THEN c.most_recent_military_pay_grade__c ELSE '' END AS MilitaryPayGrade,
CASE WHEN ca.Price_Quoted_1__c IS NOT NULL THEN ca.Price_Quoted_1__c ELSE '' END AS "price/termquoted",
CASE WHEN ca.Move_in_Date__c IS NOT NULL THEN to_char(ca.Move_in_Date__c AT TIME ZONE 'US/Pacific', 'MM/DD/YYYY') ELSE '' END AS MoveinDate,
CASE WHEN ca.Of_Occupants__c::varchar IS NOT NULL THEN ca.Of_Occupants__c::varchar ELSE '' END AS "#occupants",
CASE WHEN ca.Bed_Count_Pref__c IS NOT NULL THEN ca.Bed_Count_Pref__c ELSE '' END AS BedCountPref,
CASE WHEN ca.Bath_Count_Pref__c IS NOT NULL THEN ca.Bath_Count_Pref__c ELSE '' END AS BathCountPref,
CASE WHEN ca.Pet_Count__c::varchar IS NOT NULL THEN ca.Pet_Count__c::varchar ELSE '' END AS "#pets",
CASE WHEN ca.Pet_Type__c IS NOT NULL THEN ca.Pet_Type__c ELSE '' END AS PetTypes,
CASE WHEN ca.Breed__c IS NOT NULL THEN ca.Breed__c ELSE '' END AS Breed,
CASE WHEN ca.Pet_Name__c IS NOT NULL THEN ca.Pet_Name__c ELSE '' END AS PetName,
CASE
WHEN (ca.Desired_Rent_Start__c IS NOT NULL AND ca.Desired_Rent_Range_End__c IS NOT NULL) THEN CONCAT(ca.Desired_Rent_Start__c,' - ',ca.Desired_Rent_Range_End__c)
ELSE ''
END AS DesiredRentRange,
CASE WHEN ca.Desired_Lease_length__c::varchar IS NOT NULL THEN ca.Desired_Lease_length__c::varchar ELSE '' END AS DesiredLeaseLength,
CASE WHEN ca.Reason_for_Moving__c IS NOT NULL THEN ca.Reason_for_Moving__c ELSE '' END AS ReasonforMoving,
CASE WHEN ca.Notes__c IS NOT NULL THEN ca.Notes__c ELSE '' END AS Notes,
CASE WHEN ca.Reasons_For_Not_Setting_a_Showing__c IS NOT NULL THEN ca.Reasons_For_Not_Setting_a_Showing__c ELSE '' END AS ReasonforNotSettingShowing,
CASE WHEN ca.CreatedDate IS NOT NULL THEN to_char(ca.CreatedDate AT TIME ZONE 'US/Pacific', 'MM/DD/YYYY HH:MI AM') ELSE '' END AS "date/timeopened",
CASE
WHEN app.appointment_date__c IS NOT NULL THEN CONCAT(to_char(app.appointment_date__c AT TIME ZONE 'US/Pacific', 'MM/DD/YYYY'),' ',app.from__c,'-',app.to__c)
ELSE ''
END AS "appointmentdate/time",
CASE WHEN ca.Yardi_Guest_Card_ID__c IS NOT NULL THEN ca.Yardi_Guest_Card_ID__c ELSE '' END AS PMSGuestCardID,
rank() OVER (PARTITION BY ca.contactid, ca.property_of_interest__c ORDER BY ca.createddate DESC)
FROM
salesforce.Case ca
INNER JOIN salesforce.Contact c on ca.ContactId = c.sfid AND c.accountId = ca.accountId
LEFT JOIN salesforce.Appointment__c app ON ca.sfid = app.case__c
LEFT JOIN salesforce.Property__c p ON p.sfid = ca.Property_of_Interest__c AND p.account__c = ca.accountId
LEFT JOIN salesforce.Floor_Plan__c fp ON ca.Floor_Plan_of_Interest__c = fp.sfid AND fp.account__c = ca.accountId
LEFT JOIN salesforce.Unit__c uc ON ca.Unit_of_Interest__c = uc.sfid AND uc.account__c = ca.accountId
WHERE
ca.Guest_Card_Status__c = 'Sent via Workflow'
AND ca.accountId = '001i000000ESO3CAAX'
AND to_char(to_char(ca.createddate AT TIME ZONE 'UTC' AT TIME ZONE 'US/Pacific','YYYY-MM-DD HH24:MI:SS')::date, 'YYYY-MM-DD') BETWEEN '2016-06-02' AND '2016-07-02'
AND to_char(c.Last_Activity__c AT TIME ZONE 'US/Pacific', 'YYYY-MM-DD') BETWEEN '2016-03-04' AND '2016-07-02'
AND ( ca.Status IN ( 'Inquiry', 'Showing Set', 'Showing Completed', 'Application Pending', 'Resident' ) )
AND ( ca.IC_Call_Answered_by_AH__c IN ( 'false', 'true' ) )
AND ( ca.origin IN ( 'Phone', 'Email', 'Voicemail', 'Chat', 'Walk-In', 'Web' ) OR ca.origin IS NULL OR ca.origin = '' ) LIMIT 20 OFFSET 0
And following is the query plan for it
We have indexes on following columns:
AccountId
createddate
Status
Origin
Using PostgreSQL.
But query is taking long time to run. Can you please suggest any optimization in it?
Thanks
Without knowing much about your data set and being unable to read the screenshot of the query plan, I see a couple easy improvements you can make.
First, your use of the indexed columns accountId, status, and origin columns is fine. However, your usage of the createddate column is flawed. By converting the column to a string and then performing a comparison after it has been converted to a string, you are no longer using the index -- Postgres must perform a full scan and run two costly to_char conversions.
Qualify on your createddate column with a comparison native to the datatype of the column.
For example, if the datatype of createdate is timestamp, then you could qualify on it like this:
AND ca.createdate BETWEEN '2016-06-02'::timestamp AND '2016-07-02'::timestamp
This will use the index and it will perform much better.
Second, make sure that you've created one index that uses all four of the columns you've listed. If you have created four separate indexes for each of those columns, then you are not realizing the full performance gains possible from indexing. An index that uses all four of the columns will allow Postgres to progressively narrow down the result set with each column. If you have four separate indexes, then Postgres can only narrow down the result set with one column.

Forcing row to the top of query result that is using an alias

I have a ListBox that's being populated by a SQL query using this statement:
SELECT '-1' as [Value], 'All' as [Text]
UNION ALL
SELECT DISTINCT user_id AS [Value], user_L_name AS [Text]
FROM [issue]
Order by [Text]
I'm trying to alphabetize all the records after "All" while keeping "All" at the top.
If I have my ORDER BY clause like this:
ORDER BY CASE WHEN [Text] = '-1' THEN 0 ELSE 1 END
I get this error:
Invalid column name 'Text'.
Any help would be greatly appreciated. Thanks
You can do this in a sub-query. I'm also assuming you meant to check if [Text] was "All" rather than "-1"
SELECT [Value], [Text]
FROM
(
SELECT '-1' as [Value], 'All' as [Text]
UNION ALL
SELECT DISTINCT user_id AS [Value], user_L_name AS [Text]
FROM [issue]
) A
Order by Case When [Text] = 'All' Then 0 Else 1 End, [Text]
Alternatively, you can Order By the [Value]:
Order by Case When [Value] = '-1' Then 0 Else 1 End, [Text]

How do I change the datatype of a newly created column in a view? SQL

I am using sql and sql-server
I have created a new column in a view with a case. The problem is the following: I believe that the newly created column has a default datatype.
My question is how do i define the datatype of a new column when creating it? I have tried using convert and cast.
ALTER VIEW [dbo].[vtbl_dim_vb]
AS
SELECT
vb_key,ver_login,
ver_name,
ver_klass_descr,
CAST(ver_klass AS varchar(40)) + ' ' + ver_klass_descr AS klass_descr_d,
store_code,
store_name,
CASE WHEN LEFT(ver_klass, 1) = 'S' THEN ver_klass ELSE NULL END AS ver_sector,
CASE WHEN LEFT(ver_klass, 1) = 'M' THEN ver_klass ELSE NULL END AS ver_metier,
CASE WHEN LEFT(ver_klass, 1) <> 'S' AND LEFT(ver_klass, 1) <> 'M' THEN ver_klass ELSE NULL END AS ver_rayon
FROM
dbo.tbl_dim_vb
I have tried to use the cast command but that didn't work:
CAST ( expression AS data_type [ ( length ) ] )
I want to know what options i have for the third case.
this is how the code looks like that I tried:
CASE WHEN LEFT(ver_klass, 1) <> 'S' AND LEFT(ver_klass, 1) <> 'M' THEN ver_klass ELSE NULL END AS CAST ( ver_rayon AS int(10) )
I need the newly created column ver_rayon to be an integer datatype.
Thanks a lot for any advice ; )
Maybe something like this:
CAST(
(
CASE
WHEN LEFT(ver_klass, 1) <> 'S' AND LEFT(ver_klass, 1) <> 'M'
THEN ver_klass
ELSE NULL
END
) AS INT)
AS ver_rayon