What am I doing wrong with the loop use in SQL - sql

I need to compare emails from tables and if they match I need to show some data from the third table and I'm trying to do that through a while loop which goes through the string of all emails and compares them and if its a match it should get the data from third table
Im pasting the query from pastebin here: https://pastebin.com/zyjcJngf
The part where I want to use the loop
select distinct Email,
CASE dbo.spValueToString((SELECT COUNT(*)
FROM tblEmailBlackList WHERE tblEmailBlackList.Email=LiveCampaign_SubscriberList_Email.Email AND tblEmailBlackList.PortalID>=-1))
WHEN 'Da' THEN
WHILE #vsi > 1
BEGIN
SET #testEmail = (SELECT LEFT(#resultCpy, CHARINDEX(',', #resultCpy) - 1)) --dobi prvi mail
SET #testEmail = (SELECT REPLACE(#testEmail, ' ', '')) --zbriše vse ' ' če obstajajo
SET #resultCpy = (SELECT SUBSTRING(#resultCpy, LEN(#testEmail) + 2, LEN(#resultCpy))) --odstani prvi mail
IF
#testEmail = Email
BREAK
ELSE
SET #vsi = #vsi - 1
END
SET #vsi = (SELECT LEN(#result) - LEN(REPLACE(#result, ',', '')) + 1)
SET #resultCpy = #result
(SELECT DISTINCT PortalLocalization.PortalName
FROM tblEmailBlackList
LEFT JOIN tblLiveCampaignSettings ON tblLiveCampaignSettings.ModuleID = tblEmailBlackList.ModuleID
LEFT JOIN PortalLocalization ON PortalLocalization.PortalID = tblEmailBlackList.PortalID AND PortalLocalization.CultureCode = 'sl-SI'
WHERE Email = #testEmail
AND tblEmailBlackList.PortalID >= 0
UNION
SELECT DISTINCT PortalLocalization.PortalName
FROM tblEmailBlackList
LEFT JOIN vw_TabModules ON vw_TabModules.ModuleID = tblEmailBlackList.ModuleID
LEFT JOIN PortalLocalization ON PortalLocalization.PortalID = vw_TabModules.PortalID AND PortalLocalization.CultureCode = 'sl-SI'
WHERE Email = #testEmail
AND tblEmailBlackList.PortalID = -1)
ELSE 'Ne' END
AS LocalBlockList
FROM LiveCampaign_SubscriberList_Email
The problem I have here is that I get an error when I add the loop in the code, but if I run the loop alone it works. I get the incorrect syntax near WHILE and The multi-part identifier "LiveCampaign_SubscriberList_Email.Email" could not be bound.

You cannot put a "WHILE" inside SELECT statement.
Try to treat your data before the SELECT, maybe inside a temp Table.

Related

How to use exists for a complete list of a product?

This is the query to find out if a particular car has W1, W2, WA, WH conditions. How can I modify my query so that I can get a list of all the cars as yes or no for these conditions?
NOTE: Here, I have put v.[carnumber] = 't8302' but I need a complete list.
SELECT
CASE
WHEN EXISTS (
SELECT co.[alias]
FROM [MTI_TAXI].[vehicle] v
LEFT JOIN [MTI_SYSTEM].[Conditions] co with (nolock) on v.DispatchSystemID = co.DispatchSystemID and (v.Conditions & co.conditionvalue > 0)
WHERE co.[alias] in ('W1', 'W2', 'WA', 'WH') and v.[DispatchSystemID] = 6 and v.[CarNumber] = 't8302')
THEN cast ('Yes' as varchar)
ELSE cast ('No' as varchar)
END AS [WATS]
OUTPUT - ( WATS - No )
But, here are all the cars but I am getting yes to WATS condition which is incorrect
enter image description here
Simply utilizing your provided filters and moving the EXISTS to be used in an OUTER APPLY statement:
SELECT
CASE
WHEN [find_wats].[Found] = 1
THEN 'Yes'
ELSE 'No'
END AS [WATS]
FROM
[MTI_TAXI].[vehicle] AS v
OUTER APPLY (SELECT TOP (1)
1 AS [Found]
FROM
[MTI_SYSTEM].[Conditions] AS co
WHERE
v.DispatchSystemID = co.DispatchSystemID
AND
(v.Conditions & co.conditionvalue > 0)
AND
co.[alias] IN ('W1', 'W2', 'WA', 'WH')
AND
v.[DispatchSystemID] = 6) AS [find_wats];
Using this set up, you can then use [find_wats].[Found] = 1 to determine that your record within the table [MTI_TAXI].[vehicle] found a match in [MTI_TAXI].[Conditions] (using your provided criteria) while still maintaining a single record in your final result set for each record originally in the table [MTI_TAXI].[vehicle].
Use count(*) to assert that there was exactly 1 row found by adding:
group by co.[alias]
having count(*) = 1
So the whole query becomes:
SELECT
CASE
WHEN EXISTS (
SELECT co.[alias]
FROM [MTI_TAXI].[vehicle] v
LEFT JOIN [MTI_SYSTEM].[Conditions] co with (nolock)
on v.DispatchSystemID = co.DispatchSystemID
and (v.Conditions & co.conditionvalue > 0)
WHERE co.[alias] in ('W1', 'W2', 'WA', 'WH')
and v.[DispatchSystemID] = 6
and v.[CarNumber] = 't8302'
group by co.[alias]
having count(*) = 1
) THEN cast ('Yes' as varchar)
ELSE cast ('No' as varchar)
end AS [WATS]

Using the results of a SQL query as parameters for a second one

Our SQL developer put together the following query to basically pull a list of any employee who has logged into our system today. This query works perfectly and will spit out a list of names. What I need to do is take the list of names it spits out and then use those in a new query to change a column on a different table for each of those names.
select distinct(t.CC_FullName) as Employee,
t.CC_Supervisor as Supervisor,
t.StaffCimID
from (
select s.*,
r.CC_FullName,
r.CC_Supervisor,
r.StaffCimID
from (
select AgentFirstName + ' ' + AgentLastName as AgentName,
Agent
from pia.dbo.Five9IntraDayExtract with(nolock)
group by AgentFirstName + ' ' + AgentLastName,
Agent
) s
inner join pia.dbo.StaffInformationNew r with(nolock)
ON CASE
WHEN s.Agent LIKE '%_manual' AND s.Agent = r.Five9Name_MTM THEN 1
WHEN s.Agent NOT LIKE '%_manual' AND s.Agent = r.Five9Name THEN 1
ELSE 0
END = 1
and r.EndDate is null
) t
where t.CC_FullName is not null
and t.StaffCimID is not null
order by t.CC_FullName, t.CC_Supervisor
so basically after that runs I get a list with three columns. I need to take the name column and basically do the following:
Update Attendance Set Seated = '1' where name = 'John Doe'
I need to do that for every result from the initial query. What's the best way to do that?
Add that to the top of your query...
Update Attendance
Set Seated = '1'
where name in
(select t.CC_FullName from (
select s.*,
r.CC_FullName,
r.CC_Supervisor,
r.StaffCimID
from (
select AgentFirstName + ' ' + AgentLastName as AgentName,
Agent
from pia.dbo.Five9IntraDayExtract with(nolock)
group by AgentFirstName + ' ' + AgentLastName,
Agent
) s
inner join pia.dbo.StaffInformationNew r with(nolock)
ON CASE
WHEN s.Agent LIKE '%_manual' AND s.Agent = r.Five9Name_MTM THEN 1
WHEN s.Agent NOT LIKE '%_manual' AND s.Agent = r.Five9Name THEN 1
ELSE 0
END = 1
and r.EndDate is null
) t
where t.CC_FullName is not null
and t.StaffCimID is not null)

Sql in sql server with convert

I am trying to use convert in an where clause in the select statement. My query looks like this:
SELECT DISTINCT TOP 10 [SurveyResult].*
,[Ticket].[RefNumber]
FROM [SurveyResult]
LEFT JOIN [Ticket] ON [SurveyResult].[TicketID] = [Ticket].[TicketID]
JOIN [SurveyResponse] AS SurveyResponse1 ON [SurveyResult].[ResultID] = SurveyResponse1.[ResultID]
JOIN [QuestionAnswer] AS QuestionAnswer1 ON SurveyResponse1.[AnswerID] = QuestionAnswer1.[AnswerID]
JOIN [SurveyQuestion] AS SurveyQuestion1 ON QuestionAnswer1.[QuestionID] = SurveyQuestion1.[QuestionID]
WHERE SurveyQuestion1.[SurveyID] = [SurveyResult].[SurveyID]
AND SurveyQuestion1.[QuestionID] = 'C86CB39A-8FE0-4FE8-B38F-17F1BE611016'
AND CONVERT(INT, SurveyResponse1.[Response]) >= 1
AND CONVERT(INT, SurveyResponse1.[Response]) <= 5
The problem is that I get some errors when converting the values to integer in the where statement.
I know I have some rows that don't contain numbers in the Response column but I filter those so without the convert part in the where clause I get only numbers so it works like this:
SELECT TOP 1000 [ResponseID]
,[ResultID]
,[Response]
FROM [WFSupport].[dbo].[SurveyResponse]
JOIN QuestionAnswer ON SurveyResponse.AnswerID = QuestionAnswer.AnswerID
WHERE QuestionAnswer.QuestionID = 'C10BF42E-5D51-46BC-AD89-E57BA80EECFD'
And in the results I get numbers but once I add the convert part in the statement I I get an error that it can't convert some text to numbers.
Either do like Mark says or just have NULL values default to something numerical, this would give you a where statement like:
WHERE SurveyQuestion1.[SurveyID] = [SurveyResult].[SurveyID]
AND SurveyQuestion1.[QuestionID] = 'C86CB39A-8FE0-4FE8-B38F-17F1BE611016'
AND CONVERT(INT, ISNULL(SurveyResponse1.[Response],0)) BETWEEN 1 AND 5
The important part is the ISNULL() function and I also used BETWEEN to avoid duplicate converts.
Try:
SELECT DISTINCT TOP 10
[SurveyResult].*,
[Ticket].[RefNumber]
FROM
[SurveyResult]
LEFT JOIN [Ticket] ON [SurveyResult].[TicketID] = [Ticket].[TicketID]
JOIN [SurveyResponse] AS SurveyResponse1
ON [SurveyResult].[ResultID] = SurveyResponse1.[ResultID]
JOIN [QuestionAnswer] AS QuestionAnswer1
ON SurveyResponse1.[AnswerID] = QuestionAnswer1.[AnswerID]
JOIN [SurveyQuestion] AS SurveyQuestion1
ON QuestionAnswer1.[QuestionID] = SurveyQuestion1.[QuestionID]
where SurveyQuestion1.[SurveyID] = [SurveyResult].[SurveyID]
AND SurveyQuestion1.[QuestionID] = 'C86CB39A-8FE0-4FE8-B38F-17F1BE611016'
AND CASE SurveyQuestion1.[QuestionID]
WHEN 'C86CB39A-8FE0-4FE8-B38F-17F1BE611016'
THEN Convert(int, SurveyResponse1.[Response])
ELSE 0
END BETWEEN 1 AND 5
(The AND SurveyQuestion1.[QuestionID] = 'C86CB39A-8FE0-4FE8-B38F-17F1BE611016' is retained in case the query is using an index on QuestionID - if not, it can be removed, as the same condition is implicit in the subsequent CASE condition.)
Try this one -
SELECT DISTINCT TOP 10 sr.*, t.[RefNumber]
FROM dbo.SurveyResult sr
JOIN dbo.SurveyResponse sr2 ON sr.[ResultID] = sr2.[ResultID]
JOIN dbo.QuestionAnswer sa ON sr2.[AnswerID] = sa.[AnswerID]
JOIN dbo.SurveyQuestion sq ON sa.[QuestionID] = sq.[QuestionID] AND sq.[SurveyID] = sr.[SurveyID]
LEFT JOIN dbo.Ticket t ON sr.[TicketID] = t.[TicketID]
WHERE sq.[QuestionID] = 'C86CB39A-8FE0-4FE8-B38F-17F1BE611016'
AND CAST(ISNULL(sr2.[Response], 0) AS INT) BETWEEN 1 AND 5

Syntax Error in CASE STATEMENT

Here is my select statement. What I'm trying to do is if an account has more than one ID, I want the phone number to be NULL, ELSE I want the phone number to = phone_number_formatted:
SELECT
v_returned_inventory.order_id,
v_live_inventory.inet_event_description,
v_live_inventory.event_time,
v_cust_phone.phone_number_formatted,
v_live_inventory.event_date,
v_returned_inventory.section_name,
v_returned_inventory.add_usr,
v_live_inventory.num_seats,
v_returned_inventory.acct_id,
v_live_inventory.class_name,
AT_trans_for_emailTrigger.email_addr,
AT_trans_for_emailTrigger.cust_name_id,
premclub.name_first + ' ' + premclub.name_last AS name
FROM
v_returned_inventory
INNER JOIN
v_live_inventory
ON
LEFT(v_returned_inventory.event_name, 6) = LEFT(v_live_inventory.event_name, 6)
AND v_returned_inventory.orderNumber = v_live_inventory.other_info_1 INNER JOIN
AT_trans_for_emailTrigger
ON v_returned_inventory.order_id = AT_trans_for_emailTrigger.order_id
LEFT OUTER JOIN
v_cust_phone
on v_cust_phone.acct_id = v_returned_inventory.acct_id
LEFT OUTER JOIN
OPENQUERY(premclub, 'select name_first, name_last, cust_name_id from dba.v_cust_name') AS premclub
ON AT_trans_for_emailTrigger.cust_name_id = premclub.cust_name_id,
**CASE
WHEN (select
count(cust_name_id)
from
v_cust_phone) > 1 then null
else v_cust_phone.phone_number_formatted
END**
You have the CASE statement in the wrong place, it needs to be in the SELECT. Based on what you currently have, it appears that you might be able to do something like this:
SELECT v_returned_inventory.order_id,
v_live_inventory.inet_event_description,
v_live_inventory.event_time,
case when phone.cnt > 1 then null else v_cust_phone.phone_number_formatted end phone_number_formatted,
v_live_inventory.event_date,
v_returned_inventory.section_name,
v_returned_inventory.add_usr,
v_live_inventory.num_seats,
v_returned_inventory.acct_id,
v_live_inventory.class_name,
AT_trans_for_emailTrigger.email_addr,
AT_trans_for_emailTrigger.cust_name_id,
premclub.name_first + ' ' + premclub.name_last AS name
FROM v_returned_inventory
INNER JOIN v_live_inventory
ON LEFT(v_returned_inventory.event_name, 6) = LEFT(v_live_inventory.event_name, 6)
AND v_returned_inventory.orderNumber = v_live_inventory.other_info_1
INNER JOIN AT_trans_for_emailTrigger
ON v_returned_inventory.order_id = AT_trans_for_emailTrigger.order_id
LEFT OUTER JOIN v_cust_phone
on v_cust_phone.acct_id = v_returned_inventory.acct_id
LEFT OUTER JOIN
(
select count(cust_name_id) cnt, cust_name_id
from v_cust_phone
group by cust_name_id
) phone
on v_cust_phone.cust_name_id = phone.cust_name_id
LEFT OUTER JOIN OPENQUERY(premclub, 'select name_first, name_last, cust_name_id from dba.v_cust_name') AS premclub
ON AT_trans_for_emailTrigger.cust_name_id = premclub.cust_name_id

Trouble with case statement

I am having problems with this case statement. I don't know what I am doing wrong but I get the error:
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
I have a case when the field equals a value then do a left outer join but if the field equals a different value then do a inner join.
This is my query:
SELECT
case
when oqt = '26' then
(Select qm.id_oqm, cast(isNull(id_eval, '') as varChar(50)) + ' - ' + qm.methodName as methodName, qm.methodName as actualMethod,cv.*
FROM OQMethods QM left outer join courseversions cv on cv.evalid = QM.id_eval and cv.courselanguage = 'EN' and cv.courseactive='Y' and cv.id_cp > 0
WHERE QM.id_oqt in (SELECT tempoq.oqt FROM tempoq INNER JOIN OQMethods ON tempoq.oqt = OQMethods.id_oqt)and active = 1)
END,
case
when oqt = '31' then
(Select qm.id_oqm, cast(isNull(id_eval, '') as varChar(50)) + ' - ' + qm.methodName as methodName, qm.methodName as actualMethod,cv.*
FROM OQMethods QM inner join courseversions cv on cv.evalid = QM.id_eval and cv.courselanguage = 'EN' and cv.courseactive='Y' and cv.id_cp > 0
where QM.id_oqt in (SELECT tempoq.oqt FROM tempoq INNER JOIN OQMethods ON tempoq.oqt = OQMethods.id_oqt) and active = 1)
END
from tempoq
The case is an expression that must evaluate to a value. The Select statements that you have return multiple values.
It would seem that you're trying to use Case like it's a C# switch? If that's the case, then you're likely better off with an IF ELSE IF construction.
It looks like you want to do something like this rather than using a CASE statement.
DECLARE #t int
-- This would contain your oqt value
SET #t =1
IF #t = 1
BEGIN
SELECT * FROM tableA
END
ELSE IF #t = 2
BEGIN
SELECT * FROM TableB
END
Select qm.id_oqm, cast(isNull(id_eval, '') as varChar(50)) + ' - ' + qm.methodName as methodName, qm.methodName as actualMethod,cv.*
FROM OQMethods QM
inner join tempoq on tempoq.oqt = QM.id_oqt
left outer join courseversions cv on cv.evalid = QM.id_eval and cv.courselanguage = 'EN' and cv.courseactive='Y' and cv.id_cp > 0
WHERE active = 1 and (tempoq.oqt = '26' or (tempoq.oqt = '31' and courseversions.* is not null))
left outer join means join OQMethods's data which even no match data from courseversions,
then filter the data with null courseversions.* that is inner join.
Hope I have the right understanding.