constraint formulation in inner join - sql

I've the following problem. Take a look at this part of query
inner join tObjClassifier azoc WITH (NOLOCK index=XAK1tDepClassifier)
on azoc.ObjType = 8
and azoc.ParentID = #ObjClassifierID
and azoc.Brief = azfo.Brief
and case
when PATINDEX( ('%' + ltrim(rtrim(azn.Brief)) + '%' ) , azoc.Param) is null then azn.NodeType = 2
else PATINDEX( ('%' + ltrim(rtrim(azn.Brief)) + '%' ) , azoc.Param)>0
end
here , I'm interested in this part
and case
when PATINDEX( ('%' + ltrim(rtrim(azn.Brief)) + '%' ) , azoc.Param) is null then azn.NodeType = 2
else PATINDEX( ('%' + ltrim(rtrim(azn.Brief)) + '%' ) , azoc.Param)>0
end
How can I do this part without getting errors. Briefly, If condition PATINDEX( ('%' + ltrim(rtrim(azn.Brief)) + '%' ) , azoc.Param)>0
not satisfied, disregard this condition and use this azn.NodeType = 2 condition. Thanks.
we can rearrange above condition as this also:
and case
when ltrim(rtrim(azn.Brief)) = azoc.Param is null then azn.NodeType = 2
else ltrim(rtrim(azn.Brief)) = azoc.Param)
end

PATINDEX returns the starting position of the first occurrence of a pattern in a specified expression, or zeros if the pattern is not found. So try use OR condition:
...
and azoc.Brief = azfo.Brief
and
(
(PATINDEX( ('%' + ltrim(rtrim(azn.Brief)) + '%' ) , azoc.Param)>0)
OR
(azn.NodeType = 2)
)

Related

Case with Like operator

Got stuck at using CASE statement with LIKE operator. In the below stored procedure all the parameters are not mandatory so when User doesn't enter PatientName for searching then the below query doesn't return expected results as the LIKE operator is outside which is obvious. I'm looking for something like this so that when User doesn't enter PatientName it will be
(c.LastName + c.Firstname) = #PatientNAme else
(c.LastName + c.Firstname) like '%' + #PatientNAme + '%'
*
(c.LastName + c.Firstname) (
CASE #PatientName
WHEN '' THEN #PatientName = (c.LastName + c.Firstname)
ELSE like '%' + #PatientName + '%'
END
)
*
CREATE proc [dbo].[SearchParkPrescriptionDetails]
#DispenseID INT,
#ParkPrescriptionReasonId INT,
#PrescriptionParkType VARCHAR(50),
#PatientName VARCHAR(120),
#User VARCHAR(120),
#fromdate DATETIME,
#todate DATETIME,
#DateWiseSearch VARCHAR(3),
#PatientID INT
AS
BEGIN
SELECT
a.ParkPrescriptionId
, a.DispenseID
, a.ParkPrescriptionReasonId
, a.ParkDate
, (c.LastName + ' ' + c.Firstname) AS PatientName
, d.PrescriptionType
, e.ParkPrescriptionReason
, a.Notes
, b.ItemCount AS TotalItems
, g.ExemptionReason
,a.[User]
FROM
ParkPrescriptionDetails a
INNER JOIN
Dis_DispenseMaster b
ON
a.DispenseID=b.DispenseID
INNER JOIN
Patient c
ON
b.PatientId = c.PatientId
INNER JOIN
Lookup_PrescriptionType d
ON
b.PrescriptionTypeId = d.PrescriptionTypeId
INNER JOIN
Lookup_ParkPrescriptionReason e
ON
a.ParkPrescriptionReasonId = e.ParkPrescriptionReasonId
LEFT JOIN
Lookup_ExemptionReason g
ON
b.ExemptionReasonId = g.ExemptionReasonId
WHERE
CONVERT(DATE, a.ParkDate) BETWEEN #fromdate AND #todate
AND a.RecallStatus = 'N'
AND a.DispenseID = ( CASE #DispenseID WHEN 0 THEN a.DispenseID ELSE #DispenseID END )
AND b.PatientId = ( CASE #PatientID WHEN 0 THEN b.PatientId ELSE #PatientID END )
AND a.ParkPrescriptionReasonId = ( CASE #ParkPrescriptionReasonId WHEN 0 THEN a.ParkPrescriptionReasonId ELSE #ParkPrescriptionReasonId END )
AND
(
c.LastName + c.Firstname
) LIKE ( CASE #PatientName WHEN '' THEN (c.LastName + c.Firstname) ELSE '%' + #PatientName + '%' END )
AND a.[User] LIKE ( CASE #User WHEN '' THEN a.[User] ELSE '%' + #User + '%' END )
AND b.ParkPrescription = ( CASE #PrescriptionParkType WHEN '' THEN b.ParkPrescription WHEN 'Park' THEN 'Y' END )
AND b.RecallPrescription = ( CASE #PrescriptionParkType WHEN '' THEN b.RecallPrescription WHEN 'Recall' THEN 'Y' END )
AND a.IsDeleted =0
END
========== Changed it Like this. Is this perfect ===========
(c.LastName + ' ' + c.Firstname) = (
CASE #PatientName
WHEN '' THEN (c.LastName + ' ' + c.Firstname)
ELSE '%' + #PatientName + '%'
END
)
Do not use CASE WHEN in where clause. Use OR
(
#PatientName = '' OR
(c.LastName + c.Firstname) LIKE '%' + #PatientName + '%'
) AND
(
#User = '' OR
a.[User] LIKE '%' + #User + '%'
) -- Same for others
instead of
(c.LastName + ' ' + c.Firstname) = (
CASE #PatientName
WHEN '' THEN (c.LastName + ' ' + c.Firstname)
ELSE '%' + #PatientName + '%'
END
)
T-SQL has two forms of CASE. You are using "Simple Case". Try "Searched Case" - e.g.:
CASE
WHEN #PatientName = '' THEN [ return something ]
WHEN #PatientName like [ pattern ] THEN [ return something ]
ELSE [ return something else ]
END

issue with CASE combined with an OR

SELECT
Siren,
CASE WHEN Code_Juridique LIKE 'M%' AND Enseigne IS NOT NULL AND Enseigne <> '' --ok
THEN 'Enseigne : ' + Enseigne
WHEN (Sigle IS NULL OR Sigle ='')
AND (Enseigne IS NULL OR Enseigne ='')
THEN '' -- ok
WHEN
(Sigle IS NOT NULL OR Sigle <> '' ) THEN 'Sigle : ' + Sigle
ELSE 'Sigle / Enseigne : ' + Sigle + ' / ' + Enseigne
END as SigleEnseigne1,
Sigle,
Enseigne,
Code_Juridique
FROM #JohnJack
The code is straightforward.
Issue lies with the third when as you can see below
I should have have nothing on my 4th and 5th line, yet it is giving me Sigle :
What I want is to have the column SigleEnseigne1 on the 4th and 5th line , to be empty
Thanks for your insights
Try this:
SELECT
Siren,
CASE WHEN ( Code_Juridique LIKE 'M%' ) AND ( IsNull( Enseigne, '' ) <> '' )
THEN 'Enseigne : ' + Enseigne
WHEN ( IsNull( RTrim(LTrim(Sigle)), '') = '') AND ( IsNull( Enseigne, '' ) = '')
THEN '' -- ok
WHEN ( IsNull( RTrim(LTrim(Sigle)), '' ) <> '' )
THEN 'Sigle : ' + RTrim(LTrim(Sigle))
ELSE
'Sigle / Enseigne : ' + IsNull( RTrim(LTrim(Sigle)), '' ) + ' / ' + Enseigne
END as SigleEnseigne1,
Sigle,
Enseigne,
Code_Juridique
FROM #JohnJack
Besides stating the obvious that a (TRUE OR FALSE) = TRUE
I would simplify and bullet proof the code by using ISNULL() and LEN().
SELECT
Siren,
CASE WHEN Code_Juridique LIKE 'M%' AND LEN(ISNULL(Enseigne,'')) > 0 --ok
THEN 'Enseigne : ' + Enseigne
WHEN (LEN(ISNULL(Sigle, '')) = 0)
AND (LEN(ISNULL(Enseigne, '')) = 0)
THEN '' -- ok
WHEN
LEN(ISNULL(Sigle, '')) > 0 THEN 'Sigle : ' + Sigle
ELSE 'Sigle / Enseigne : ' + ISNULL(Sigle, '') + ' / ' + ISNULL(Enseigne, '')
END as SigleEnseigne1,
Sigle,
Enseigne,
Code_Juridique
FROM #JohnJack
How would your code react if those fields contain whitespaces? LEN automatically trims trailing whitespaces.
This line is causing your probelm:
(Sigle IS NOT NULL OR Sigle <> '' ) THEN 'Sigle : ' + Sigle
...but that is only obvious because you state that you dont want this result. Other than that the code acts as would be expected.
The simplest solution would be to take out:
'Sigle : ' + Sigle
but that may or may not be precisely what you are looking for. Based on the given information it is the solution but there is not an abundance of information to work off
If you are trying to get non null values to print then it should be an AND rather than an OR. When you use an OR it will return true if EITHER condition is true.
I'm not sure why you have this when
WHEN (Sigle IS NULL OR Sigle = '')
AND (Enseigne IS NULL OR Enseigne ='')
THEN '' -- ok
As what you want is SigleEnseigne1 to be NULL or '' when Sigle is NULL or '' don't you need this when instead
WHEN (Sigle IS NULL OR Sigle = '') THEN ''
There can also be the problem that Sigle is not the empty string and has whitespaces. You can use the LTRIM() and RTRIM() functions
It took me the weekend but actually, I figured out My mistake.
Sorry for the mess
The answer is below
SELECT
Siren,
CASE WHEN ( Code_Juridique LIKE 'M%' ) AND ( IsNull( Enseigne, '' ) <> '' )
THEN 'Enseigne : ' + Enseigne
WHEN ( IsNull( RTrim(LTrim(Sigle)), '') = '') AND ( IsNull( Enseigne, '' ) = '')
THEN '' -- ok
WHEN (Sigle IS NOT NULL OR Sigle <> '') AND (Enseigne IS NULL OR Enseigne = '')
THEN 'Sigle : ' + RTrim(LTrim(Sigle))
WHEN (Sigle IS NULL OR Sigle = '') AND (Enseigne IS NOT NULL OR Enseigne <> '')
THEN ''
WHEN
(Sigle IS NOT NULL OR Sigle <> '') AND (Enseigne IS NOT NULL OR Enseigne <> '')
THEN 'Sigle / Enseigne : ' + IsNull( RTrim(LTrim(Sigle)), '' ) + ' / ' + Enseigne
END as SigleEnseigne1
FROM John_Jack
Have a great end of the year

SQL Server stored proc substitute an empty string if column is empty or null

I need to check to see if a certain coloumn in my stored proc is either empty or null.
This is a snippet of what I have right now:
SELECT * ,
CASE WHEN a.USER IS NULL
THEN b.ROLE
ELSE ISNULL(a.FirstName,'') + ' ' + (ISNULL(a.MiddleName+' ','') + ISNULL(a.LastName,'')
END AS 'CustomerName'
I am checking to see if a.MiddleName is NULL but how do I also check to see if its empty and if its empty to just insert a empty string (no space)?
Thanks
Change to
SELECT
* ,
CASE
WHEN a.USER IS NULL
THEN b.ROLE
ELSE CASE
WHEN ISNULL(a.MiddleName, '') = ''
THEN ISNULL(a.FirstName,'') + ' ' + ISNULL(a.LastName,'')
ELSE ISNULL(a.FirstName,'') + ' ' + a.MiddleName + ' ' + ISNULL(a.LastName,'')
END
END AS 'CustomerName'
Another sollution is:
SELECT * ,
CASE WHEN a.USER IS NULL
THEN b.ROLE
ELSE ISNULL(a.FirstName,'') + replace( ( ' ' + ISNULL(a.MiddleName+' ',' '),' ',' ') + ISNULL(a.LastName,'')
END AS 'CustomerName'

Can't put a second "with" statement into the query

I have a query - which is combining with a Union statement the 5 columns into 2 columns.
So basically - an ID + Some Information. As the ID could be in column 2-5 - several times... I rearranged to be everything in one ID column + the text.
Now - I wanted to use a second "with" statement - to combine the IDs of several rows - with a XML path. But here I got stuck.
That is the code - which gives me the two column - with content as expected:
With
STall as (Select
'Status: ' + ST.Status + Char(10) + 'Crew Information:' + Char(10) +
'Instructor: ' + ST.IP + Char(10) + 'Student: ' + ST.SP + Char(10) + Case
When ST.ACM1 = 'NA' Then '' Else 'ACM1: ' + ST.ACM1 + Char(10) End + Case
When ST.ACM2 = 'NA' Then '' Else 'ACM2: ' + ST.ACM2 + Char(10)
End + 'Lesson: ' + ST.Lesson + Char(10) + Case
When ST.ScheduleRemarks = '' Then ''
Else ' REM:' + ST.ScheduleRemarks + Char(10)
End + 'Equipment: ' + ST.EquipmentName + ' (' + ST.Callsign + ')' +
Char(10) + 'Start: ' + Convert(VARCHAR(10),ST.ScheduleTO,104) + ' - ' +
Convert(VARCHAR(5),ST.ScheduleTO,108) + ' UTC' + Char(10) + 'End: ' +
Convert(VARCHAR(10),ST.ScheduleTD,104) + ' - ' +
Convert(VARCHAR(5),ST.ScheduleTD,108) + ' UTC' + Char(10) + Case
When ST.ATC = 'NA' Then '' Else ST.ATC End As SInfo,
ST.IDIP,
ST.IDSP,
ST.IDA1,
ST.IDA2
From
(Select
Case When Schedule.StatusRelease = 1 Then 'OK' Else Case
When Schedule.StatusRequest = 1 Then 'STBY' Else 'N/A' End
End As Status,
Schedule.ContactIDIP,
Schedule.ContactIDSP,
MasterLesson.Lesson,
Equipment.EquipmentName,
CallSignList.Callsign,
Schedule.Meeting,
Schedule.ScheduleRemarks,
Schedule.StatusRelease,
Schedule.StatusRequest,
Schedule.ScheduleDay,
ContactList.FullNameTLC As IP,
ContactList1.FullNameTLC As SP,
Case When Schedule.ContactIDACM1 = 0 Then 'NA'
Else ContactList2.FullNameTLC End As ACM1,
Case When Schedule.ContactIDACM2 = 0 Then 'NA'
Else ContactList3.FullNameTLC End As ACM2,
Schedule.ScheduleTO,
Schedule.ScheduleTD,
Case When Schedule.RouteID = 0 Then 'NA'
Else 'Route: ' + Airport.ICAO + ' - ' + Case
When IsNull(Airport1.ICAO, 'NA') = 'NA' Then ' '
Else Airport1.ICAO + ' - ' End + Airport2.ICAO + Char(10) + Char(13)
End As ATC,
ContactList.Id As IDIP,
ContactList1.Id As IDSP,
ContactList2.Id As IDA1,
ContactList3.Id As IDA2
From
Schedule Inner Join
StudentLesson On Schedule.ScheduleLessonID = StudentLesson.StudentLessonID
Inner Join
MasterLesson On StudentLesson.LessonID = MasterLesson.ID Inner Join
Equipment On Schedule.EquipmentID = Equipment.ID Left Join
CallSignList On CallSignList.ID = Schedule.CallSignListID Left Join
Route On Route.ID = Schedule.RouteID Inner Join
ContactList On ContactList.Id = Schedule.ContactIDIP Inner Join
ContactList ContactList1 On ContactList1.Id = Schedule.ContactIDSP
Left Join
ContactList ContactList2 On Schedule.ContactIDACM1 = ContactList2.Id
Left Join
ContactList ContactList3 On Schedule.ContactIDACM2 = ContactList3.Id
Left Join
Airport On Route.AirportID_Dep = Airport.ID Left Join
Airport Airport1 On Route.AirportID_Via = Airport1.ID Left Join
Airport Airport2 On Route.AirportID_Arr = Airport2.ID
Where
((Schedule.StatusRelease = 1) Or
(Schedule.StatusRequest = 1)) And
Schedule.ScheduleDay = '21.02.2014') As ST)
Select Distinct
STall.IDIP,SInfo
From
STall
where STall.IDIP > 0
UNION
Select Distinct
STall.IDSP,SInfo
From
STall
where STall.IDSP > 0
UNION
Select Distinct
STall.IDA1,SInfo
From
STall
where STall.IDA1 > 0
UNION
Select Distinct
STall.IDA2,SInfo
From
STall
where STall.IDA2 > 0
Now - I tried to add another With STtotal as ( in the beginning...
and
)
Select Distinct
STsub.IDIP,
SubString((Select
+Char(10) + STn1.SInfo As [text()]
From
STsub STn1
Where
STn1.IDIP = STtotal.IDIP
Order By
STn1.IDIP
For Xml Path('')), 2, 1000) ScheduleInfo
From
STtotal
But I get an error - with wrong Statement at "with".
Maybe there is another approach - how to combine - the "Info Text" column with all IDs - which could be in column 2-5.
Thanks for any imput
Separate your CTEs with a comma; the WITH only needs to be specified once:
;WITH CTE1 AS (
...
), CTE2 AS (
...
)
SELECT ...
Did you remember to put a semi colon at the end of the first statement?

pull SQL results for search criteria conditions

Notice the 2 queries below. The 1st one does a union on 4 queries. I'm trying to write #2 for search conditions based on the 3 SQL variables prefixed with an "#". So rather than doing a union, we have to take all 3 parameters into consideration for the search. And if any parameter/variable is '' (or NULL), just ignore that condition, but still perform the search. But all fields have to combine with each other for a single row/record in the search results.
How do I re-write QUERY #2 so that it pulls results based on the search conditions (#companyName, #primaryPhone and #postalCode)? I think each section in the where clause has to have some OR condition (so it doesn't skip the row for a ''/NULL search condition), but I'm curious how this is typically done. The #primaryPhone part of the where clause is a little trickier because it looks at both phone and fax.
QUERY #1
SELECT tempTable.optionValue, tempTable.optionText FROM (
SELECT
address.addressid AS 'optionValue',
address.name AS 'optionText'
FROM
dbo.address
WHERE
addressid=1
UNION
-- Company Name internal partial match
SELECT
address.addressid AS 'optionValue',
('[' + CAST(address.addressid AS NVARCHAR(10)) + '] ' + ISNULL(address.name,'') + ', ' + ISNULL(address1,'') + ', ' + ISNULL(city,'') + ' ' + ISNULL(statecode,'') + ', ' + ISNULL(countrycode,'') + ' ' + ISNULL(postalcode,'')) AS 'optionText'
FROM
dbo.[address]
LEFT OUTER JOIN dbo.contact_address ON dbo.address.addressid = dbo.contact_address.addressid
LEFT OUTER JOIN dbo.clientcontact ON dbo.contact_address.contactid = dbo.clientcontact.contactid
LEFT OUTER JOIN dbo.client ON dbo.clientcontact.clientid = dbo.client.clientid
LEFT OUTER JOIN dbo.contact ON dbo.contact_address.contactid = dbo.contact.contactid
WHERE
client.name IS NOT NULL
AND client.name != ''
AND #companyName != ''
AND #companyName IS NOT NULL
AND client.name LIKE '%' + #companyName + '%'
AND clientcontact.contacttypeid = 3 --primary contacts only
UNION
-- Primary Phone/Fax internal partial match
SELECT
address.addressid AS 'optionValue',
('[' + CAST(address.addressid AS NVARCHAR(10)) + '] ' + ISNULL(address.name,'') + ', ' + ISNULL(address1,'') + ', ' + ISNULL(city,'') + ' ' + ISNULL(statecode,'') + ', ' + ISNULL(countrycode,'') + ' ' + ISNULL(postalcode,'')) AS 'optionText'
FROM
dbo.[contact]
LEFT OUTER JOIN dbo.clientcontact ON dbo.contact.contactid = dbo.clientcontact.contactid
LEFT OUTER JOIN dbo.contact_address ON dbo.contact.contactid = dbo.contact_address.contactid
LEFT OUTER JOIN dbo.address ON dbo.contact_address.addressid = dbo.address.addressid
WHERE
(
contact.dayphone IS NOT NULL
AND contact.dayphone != ''
AND #primaryPhone != ''
AND #primaryPhone IS NOT NULL
AND contact.dayphone LIKE '%' + #primaryPhone + '%'
)
OR
(
contact.fax IS NOT NULL
AND contact.fax != ''
AND #primaryPhone != ''
AND #primaryPhone IS NOT NULL
AND contact.fax LIKE '%' + #primaryPhone + '%'
)
AND clientcontact.contacttypeid = 3 --primary contacts only
UNION
SELECT
address.addressid AS 'optionValue',
('[' + CAST(address.addressid AS NVARCHAR(10)) + '] ' + ISNULL(address.name,'') + ', ' + ISNULL(address1,'') + ', ' + ISNULL(city,'') + ' ' + ISNULL(statecode,'') + ', ' + ISNULL(countrycode,'') + ' ' + ISNULL(postalcode,'')) AS 'optionText'
FROM
dbo.[contact]
LEFT OUTER JOIN dbo.clientcontact ON dbo.contact.contactid = dbo.clientcontact.contactid
LEFT OUTER JOIN dbo.contact_address ON dbo.contact.contactid = dbo.contact_address.contactid
LEFT OUTER JOIN dbo.address ON dbo.contact_address.addressid = dbo.address.addressid
WHERE
#postalCode != ''
AND #postalCode IS NOT NULL
AND address.postalcode LIKE #postalCode + '%'
AND clientcontact.contacttypeid = 3 --primary contacts only
) AS tempTable
QUERY #2 (SEARCH)
SELECT tempTable.optionValue, tempTable.optionText FROM (
SELECT
address.addressid AS 'optionValue',
address.name AS 'optionText'
FROM
dbo.address
WHERE
addressid=1
UNION
SELECT
address.addressid AS 'optionValue',
('[' + CAST(address.addressid AS NVARCHAR(10)) + '] ' + ISNULL(address.name,'') + ', ' + ISNULL(address1,'') + ', ' + ISNULL(city,'') + ' ' + ISNULL(statecode,'') + ', ' + ISNULL(countrycode,'') + ' ' + ISNULL(postalcode,'')) AS 'optionText'
FROM
dbo.[address]
LEFT OUTER JOIN dbo.contact_address ON dbo.address.addressid = dbo.contact_address.addressid
LEFT OUTER JOIN dbo.clientcontact ON dbo.contact_address.contactid = dbo.clientcontact.contactid
LEFT OUTER JOIN dbo.client ON dbo.clientcontact.clientid = dbo.client.clientid
LEFT OUTER JOIN dbo.contact ON dbo.contact_address.contactid = dbo.contact.contactid
WHERE
(
client.name IS NOT NULL
AND client.name != ''
AND #companyName != ''
AND #companyName IS NOT NULL
AND client.name LIKE '%' + #companyName + '%'
)
AND
(
(
contact.dayphone IS NOT NULL
AND contact.dayphone != ''
AND #primaryPhone != ''
AND #primaryPhone IS NOT NULL
AND contact.dayphone LIKE '%' + #primaryPhone + '%'
)
OR
(
contact.fax IS NOT NULL
AND contact.fax != ''
AND #primaryPhone != ''
AND #primaryPhone IS NOT NULL
AND contact.fax LIKE '%' + #primaryPhone + '%'
)
)
AND
(
#postalCode != ''
AND #postalCode IS NOT NULL
AND address.postalcode LIKE #postalCode + '%'
)
AND clientcontact.contacttypeid = 3 --primary contacts only
) AS tempTable
EDIT New Rules
| Field = '' or NULL | Field != '' or NULL
---------------------+----------------------+-----------------------
Param = '' or NULL | Include Record | Include Record
---------------------+----------------------+-----------------------
Param != '' or NULL | Exclude Record | Include if Match
WHERE
(
#companyName = ''
OR #companyName IS NULL
OR client.name LIKE '%' + #companyName + '%'
)
AND
(
(
#primaryPhone = ''
OR #primaryPhone IS NULL
OR contact.dayphone LIKE '%' + #primaryPhone + '%'
)
OR
(
#primaryPhone = ''
OR #primaryPhone IS NULL
OR contact.fax LIKE '%' + #primaryPhone + '%'
)
)
AND
(
#postalCode = ''
OR #postalCode IS NULL
OR address.postalcode LIKE #postalCode + '%'
)
AND clientcontact.contacttypeid = 3 --primary contacts only
#postalCode != ''
AND #postalCode IS NOT NULL
AND address.postalcode LIKE #postalCode + '%'
could be written as
AND address.postalcode LIKE IsNull(#postalCode, '') + '%'
no need for testing that you have a variable at all, sql will ignore it in the execution when = '%'
a mass of ORs in my experience will really slow down the query (but look at the exe plan anyway). this is a heck of a lot easier on the eye also imo.