Concatenating 2 columns in sql and applying like operation on the result - sql

SELECT
CONCAT(SG.firstname +' ', SG.lastName) AS 'Name',
SG.entityId 'ID',
dbo.GetTitleDescriptionByEntityID(SG.entityId) 'Title',
CASE ISNULL(EC.address2, '')
WHEN '' THEN EC.address1
ELSE EC.address1 +', ' + EC.address2
END +', ' + EC.city + ', ' + LDState.ItemName + ', ' + EC.zip 'Address',
CR.clinicalRate
FROM
StaffGeneral SG WITH (NOLOCK)
JOIN
LookupDetails LD WITH (NOLOCK) ON SG.employeeStatus = LD.lookupDetailsId AND LD.ItemAbbreviation = 'SCSSC'
JOIN
othersRating or1 WITH (nolock) ON SG.entityId = or1.entityId AND dateRated = (SELECT TOP 1 MAX(dateRated) FROM OthersRating r1 WITH (nolock) WHERE r1.entityid = SG.entityId)
JOIN
LookupDetails LDRating with (nolock) ON or1.rating = LDRating.lookupDetailsId AND LDRating.ItemAbbreviation NOT IN ('RTNP', 'RTDNU', 'RTPENDING', 'RTDELETE', 'RTTERMI')
JOIN
EntityContacts EC with (nolock) ON SG.entityId = EC.entityId AND (eC.contactId = 'General' or EC.contactId = 'General1') AND EC.deleted = 0
JOIN
LookupDetails LDState WITH (NOLOCK) ON EC.state = LDState.lookupDetailsId
JOIN
ContractorRate CR ON SG.entityId = CR.entityId AND CR.deleted = 0
WHERE
SG.isActive = 0 AND SG.deleted = 0
AND ((SG.entityId = #subContractorID) OR (#subContractorID IS null))
AND ((#subContractorName IS NULL) OR ((EC.firstName + ' ' + EC.lastName) LIKE #subContractorName + '%'))
In the above query I wanted to concat the first and last name with space and query it against the input to the stored procedure #subcontractorname.
When the subcontractorname is null that is fine but I am not able to get results when it jumps to Or clause .
Tried the SQL Server Profiler but does not show anything how the query is formed
I tried executing the SQL by putting the whole SQL in a var but I am hitting the problem of varchar(max).
Please advise

Related

Why query takes more time to execute when I use if else statement in stored procedure?

I have used below query in my stored procedure. When I am using if else statement in the stored procedure query takes more time to execute. When I remove if else statement query takes less time to return result.
If #P_Make = 'ALL' Or IsNull(#P_Make, '') = ''
Begin
Set #P_Make = '%';
End
Else
Begin
Set #P_Make = #P_Make + '%';
End
If #P_Model = 'ALL' Or IsNull(#P_Model, '') = ''
Begin
Set #P_Model = '%';
End
Else
Begin
Set #P_Model = #P_Model + '%';
End
If #P_Location = 'ALL' Or IsNull(#P_Location, '') = ''
Begin
Set #P_Location = '%';
End
Else
Begin
Set #P_Location = #P_Location + '%';
End
If #P_City = 'ALL' Or IsNull(#P_City, '') = ''
Begin
Set #P_City = '%';
End
Else
Begin
Set #P_City = #P_City + '%';
End
If #P_Category = 'ALL' Or IsNull(#P_Category, '') = ''
Begin
Set #P_Category = '%';
End
Else
Begin
Set #P_Category = Case When #P_Category = 'Bikes & Scooters' Then '2W%'
When #P_Category = '3 Wheelers' Then '3W%'
When #P_Category = 'Cars & SUVs' Then '4W%'
When #P_Category = 'Trucks' Then 'CV%'
When #P_Category = 'Farm Equipments' Then 'FE%'
When #P_Category = 'Industrial Equipments' Then 'IE%'
When #P_Category = 'Construction Equipments' Then 'CE%'
Else #P_Category + '%'
End
End
If #P_Service = 'ALL' Or IsNull(#P_Service, '') = ''
Begin
Set #P_Service = ''
End
Select Count(C.Sal_Pk_Id)
From dbo.Auction (NoLock) A
Inner Join dbo.PLACE (NoLock) B On A.Auc_Place_Fk_Id = B.Place_Pk_Id
Inner Join dbo.SALES_DETAILS (NoLock) C On A.Auc_Code = C.Sal_Auc_Code
Inner Join dbo.AUCTIONSERVICES (NoLock) D On C.Sal_Regno = D.Auc_Service_Regno And C.Sal_Auc_Code = D.Auc_Service_Auctioncode
Inner Join dbo.LOT (NoLock) E On C.Sal_Lot_No = E.Lot_Lot_No And C.Sal_Auc_Code = E.Lot_Auc_Code
Inner Join dbo.INVENTORY (NoLock) F On C.Sal_Regno = F.Inv_H_Reg_No
Where C.[Status] = 'L' And E.Lot_Sold_Status = 'S'
And IsNull(B.Place_City, '') Like #P_City And IsNull(B.Place_State, '') Like #P_Location
And IsNull(F.Inv_H_Category, '') Like #P_Category And IsNull(F.Inv_H_Mfg_Name, '') Like #P_Make
And IsNull(F.Inv_H_Model, '') Like #P_Model
Query without if else statement:
Select Count(C.Sal_Pk_Id)
From dbo.Auction (NoLock) A
Inner Join dbo.PLACE (NoLock) B On A.Auc_Place_Fk_Id = B.Place_Pk_Id
Inner Join dbo.SALES_DETAILS (NoLock) C On A.Auc_Code = C.Sal_Auc_Code
Inner Join dbo.AUCTIONSERVICES (NoLock) D On C.Sal_Regno = D.Auc_Service_Regno And C.Sal_Auc_Code = D.Auc_Service_Auctioncode
Inner Join dbo.LOT (NoLock) E On C.Sal_Lot_No = E.Lot_Lot_No And C.Sal_Auc_Code = E.Lot_Auc_Code
Inner Join dbo.INVENTORY (NoLock) F On C.Sal_Regno = F.Inv_H_Reg_No
Where C.[Status] = 'L' And E.Lot_Sold_Status = 'S'
And (#P_City = '' Or IsNull(B.Place_City, '') = #P_City)
And (#P_Location= '' Or IsNull(B.Place_State, '') = #P_Location)
And (#P_Category = '' Or IsNull(F.Inv_H_Category, '') = #P_Category)
And (#P_Make = '' Or IsNull(F.Inv_H_Mfg_Name, '') = #P_Make)
And (#P_Model = '' Or IsNull(F.Inv_H_Model, '') = #P_Model)
Why the query output takes less time when I remove if else statement in the stored procedure?
There's two main reasons - like and execution plan.
like '%something' is the slowest possible thing you can filter by - it means going row by row, reading the whole data in the column and doing a comparison. It can't use any index seeks, only scans.
Second, you only get one execution plan, based on the first way the procedure is called. This pretty much guarantees that for any other input data, the performance will suffer. In your second example, while the plan is again sub-optimal and dependent on the initial inputs, it doesn't completely ignore all the possible filters - it just optimizes based on statistics.
Dynamic filters aren't something nobody tried to solve before. Learn from the best: http://www.sommarskog.se/dyn-search.html
I think the query without if else is faster because it does not have a Like operator
Where C.[Status] = 'L' And E.Lot_Sold_Status = 'S'
And IsNull(B.Place_City, '') Like #P_City And IsNull(B.Place_State, '') Like #P_Location
And IsNull(F.Inv_H_Category, '') Like #P_Category And IsNull(F.Inv_H_Mfg_Name, '') Like #P_Make
And IsNull(F.Inv_H_Model, '') Like #P_Model
and I suppose that the second query can use indexes more efficiently. The first and second queries are different, please look at Actual Execution Plan and you will realize why it happens.

SQL Error The multi-part identifier could not be bound

When I'm trying to execute this query, I get "The multi-part identifier "#EachEmployee.ResultID" could not be bound." error.
DECLARE #QueryText VARCHAR(1000)
SET #QueryText = '
UPDATE #EachEmployee2
SET #EachEmployee2.CorrectAnswerCount = (
SELECT COUNT (TMID)
FROM
' + #WorkDatabaseName + '.dbo.TestBlockTM AS TBTM,
' + #WorkDatabaseName + '.dbo.TestResultTM AS TRTM
WHERE 1 = 1
AND TBTM.TMID = TRTM.OtvetID
AND TBTM.TMPID = TRTM.VoprosID
AND TRTM.TestResultID = #EachEmployee2.ResultID
)
WHERE
#EachEmployee2.IsGroup = 0 AND #EachEmployee2.BlockID = 1'
EXECUTE(#QueryText)
However, the similar query is working perfectly:
UPDATE #EachEmployee2
SET #EachEmployee2.ResultID = (
SELECT TOP 1 TestResultID
FROM #AnswersList AS a
WHERE 1 = 1
AND a.SID = #EachEmployee2.SID
AND a.UserID = #EachEmployee2.UserID
)
Can someone tell what's a problem here? Thanks and appreciate your help.
try this
SET #QueryText = '
UPDATE emp
SET emp.CorrectAnswerCount = (
SELECT COUNT (TMID)
FROM
' + #WorkDatabaseName + '.dbo.TestBlockTM AS TBTM,
' + #WorkDatabaseName + '.dbo.TestResultTM AS TRTM
WHERE 1 = 1
AND TBTM.TMID = TRTM.OtvetID
AND TBTM.TMPID = TRTM.VoprosID
AND TRTM.TestResultID = emp.ResultID
)
From #EachEmployee2 emp
WHERE
emp.IsGroup = 0 AND emp.BlockID = 1'
Can you try this query and tell me if the error still occurs:
SET #QueryText = '
UPDATE #EachEmployee2
SET CorrectAnswerCount = (
SELECT COUNT (TMID)
FROM
' + #WorkDatabaseName + '.dbo.TestBlockTM AS TBTM,
INNER JOIN ' + #WorkDatabaseName + '.dbo.TestResultTM AS TRTM ON TRTM.OtvetID = TBTM.TMID
AND TRTM.VoprosID = TBTM.TMPID
AND TRTM.TestResultID = E.ResultID
)
FROM #EachEmployee2 E
WHERE E.IsGroup = 0
AND E.BlockID = 1'
I added the FROM clause and modified a bit the subquery in order to replace the old SQL syntax by an explicit INNER JOIN clause.
Hope this will help

How to Convert the SQL Server Query to Equivelent SQLite Query?

I have this query which works in SQL server:
SELECT
T_Cbt.cbtName,
T_HDD.hddName,
T_HDD.ip,
T_HDD.compName,
T_Cbt.mobRack,
T_HDD.size,
T_OS.osName + ' ' + T_OS.osVersion + ' - ' + T_OS.osLanguage AS Expr1,
T_OS.osBit,
T_SWList.swName + ' ' + T_SWDetails.swVersion + ' - ' + T_SWDetails.swLang + ' ' + T_SWDetails.swArch AS Expr2
FROM T_OS INNER JOIN
T_Cbt INNER JOIN
T_HDD ON T_Cbt.cbtId = T_HDD.cbtId ON T_OS.id = T_HDD.osId INNER JOIN
T_Division ON T_HDD.division = T_Division.divId LEFT OUTER JOIN
T_SWDetails INNER JOIN
T_SW ON T_SWDetails.sdPk = T_SW.swdid INNER JOIN
T_SWList ON T_SWDetails.swdId = T_SWList.swId ON T_HDD.hddid = T_SW.hddid
WHERE T_Cbt.cbtName <> 'FREE'
ORDER BY T_Cbt.purpose
While i am executing this query in Sqlite i get error like Error while executing query: near "ON": syntax error How to fix it?
SQLite does not allow nesting JOIN and ON arbitrarily. Reordering your JOINs to not use nesting should allow the query to execute without a problem;
SELECT
T_Cbt.cbtName, T_HDD.hddName, T_HDD.ip, T_HDD.compName,
T_Cbt.mobRack, T_HDD.size,
T_OS.osName || ' ' || T_OS.osVersion || ' - ' || T_OS.osLanguage AS Expr1,
T_OS.osBit, T_SWList.swName || ' ' || T_SWDetails.swVersion || ' - ' ||
T_SWDetails.swLang || ' ' || T_SWDetails.swArch AS Expr2
FROM T_OS
INNER JOIN T_HDD ON T_OS.id = T_HDD.osId
INNER JOIN T_Cbt ON T_Cbt.cbtId = T_HDD.cbtId
INNER JOIN T_Division ON T_HDD.division = T_Division.divId
INNER JOIN T_SW ON T_HDD.hddid = T_SW.hddid
LEFT OUTER JOIN T_SWDetails ON T_SWDetails.sdPk = T_SW.swdid
INNER JOIN T_SWList ON T_SWDetails.swdId = T_SWList.swId
WHERE (T_Cbt.cbtName <> 'FREE')
ORDER BY T_Cbt.purpose

Concatenating row values using Inner Join

I have this query that I'm using to join two tables for an update statement. This is the query that I built:
DECLARE #DocHoldReasons VARCHAR(8000)
SET #DocHoldReasons = 'DocType Hold'
UPDATE dbo.EpnPackages
SET Error = 1, Msg = COALESCE (#DocHoldReasons + ': ', '') + cv.Value
FROM EpnPackages p
INNER JOIN EpnCountyValues cv ON cv.CountyId = p.CountyId and cv.ValueName = 'DocHoldReason'
WHERE p.Status = 1000
AND p.Error = 0
There are two rows in the EpnCountyValues table with the same ValueName, and I need them both concatenated, and I'm having a tough time doing it. All I can get is the first row value. This is what my resulting string should look like - 'DocType Hold: Test: Test.124.'
eidt: I need the rows with the same ValueName to be concatenated for the update query. There could be more than two rows with ValueName = DocHoldReason
Here's the structure of the EpnCountyValues table:
CountyValueId CountyId ValueName Value
1 1 DocHoldReason Test
2 2 xyz Test1
3 3 DocHoldReason Test.124.
Any help would be greatly appreciated. Thanks!
You can do what you want by pre-aggregating the table before the join. If there are only two values and you don't care about the order, then this will work:
DECLARE #DocHoldReasons VARCHAR(8000);
SET #DocHoldReasons = 'DocType Hold';
UPDATE dbo.EpnPackages
SET Error = 1,
Msg = (COALESCE(#DocHoldReasons + ': ', '') + minv +
(case when minv <> maxv then ': ' + maxv else '' end)
)
FROM EpnPackages p INNER JOIN
(select cv.CountyId, min(cv.value) as minv, max(cv.value) as maxv
from EpnCountyValues cv
where cv.ValueName = 'DocHoldReason'
) cv
ON cv.CountyId = p.CountyId
WHERE p.Status = 1000 AND p.Error = 0;
EDIT:
For more than two values, you have to do string concatenation. That is "unpleasant" in SQL Server. Here is the approach:
DECLARE #DocHoldReasons VARCHAR(8000);
SET #DocHoldReasons = 'DocType Hold';
UPDATE dbo.EpnPackages
SET Error = 1,
Msg = (COALESCE(#DocHoldReasons + ': ', '') +
stuff((select ': ' + cv.value
from EpnCountyValues cv
where cv.ValueName = 'DocHoldReason' and
cv.CountyId = p.CountyId
for xml path ('')
), 1, 2, '')
)
WHERE p.Status = 1000 AND p.Error = 0;
This version does it using a correlated subquery rather than a join with an aggregation.
EDIT II:
You can fix this with an additional coalesce:
DECLARE #DocHoldReasons VARCHAR(8000);
SET #DocHoldReasons = 'DocType Hold';
UPDATE dbo.EpnPackages
SET Error = 1,
Msg = (COALESCE(#DocHoldReasons + ': ', '') +
COALESCE(stuff((select ': ' + cv.value
from EpnCountyValues cv
where cv.ValueName = 'DocHoldReason' and
cv.CountyId = p.CountyId
for xml path ('')
), 1, 2, ''), '')
)
WHERE p.Status = 1000 AND p.Error = 0;
You can join the EpnCountyValues table twice!
Something like this,
DECLARE #DocHoldReasons VARCHAR(8000)
SET #DocHoldReasons = 'DocType Hold'
Select #DocHoldReasons + ': ' + ev1.Value + ': ' + ev2.Value
From EpnPackages p
Join EpnCountyValues ev1 on p.packageID = ev1.packageID
Join EpnCountyValues ev2 on ev1.ValueName = ev2.ValueName
Where ev1.ValueName = 'DocHoldRegion'
And p.status = 1000
And p.error = 0
Does that select look right to you? If so, run the update. I always try to run a select before an update. I have to admit, I'm a bit confused why you're joining on CountyID, but then it seems like you'll be updating the values from different counties?

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?