Update AND select in one statement (with 1 WHERE clause) - sql

How can I simplify the following SQL statement to 1 WHERE clause:
SELECT *
FROM tabA
WHERE (colCar IS NULL OR colCar = '')
OR (colBike IS NULL OR colBike = '')
OR (colTrain IS NULL OR colTrain = '')
UPDATE tabA
SET Distance = 999
WHERE (colCar IS NULL OR colCar = '') OR
(colBike IS NULL OR colBike = '') OR
(colTrain IS NULL OR colTrain = '')
This statement makes no sense, but it is working fine.
I just want avoid to use the WHERE clause twice.
Some ideas?
Thanks in advance!
Mike
SQL Server
SELECT *
FROM tabA
WHERE (colCar IS NULL OR colCar = '')
OR (colBike IS NULL OR colBike = '')
OR (colTrain IS NULL OR colTrain = '')
UPDATE tabA
SET Distance = 999
WHERE (colCar IS NULL OR colCar = '')
OR (colBike IS NULL OR colBike = '')
OR (colTrain IS NULL OR colTrain = '')
Code is working fine

You can use OUTPUT clause to return updated rows:
UPDATE tabA
SET Distance = 999
OUTPUT deleted.colCar
, inserted.colCar
, deleted.colBike
, inserted.Distance
WHERE (colCar IS NULL OR colCar = '') OR
(colBike IS NULL OR colBike = '') OR
(colTrain IS NULL OR colTrain = '')

Related

Select only the top 1 value from a column in a table that I'm joining?

So below is the query, how can I store only the top 1 "agencyID" into DCA.AgencyID? I know that the way the query below is structured now it would select all the "agencyID" values and not just the top 1.
SELECT AP.ID
,DCA.AgencyID as agencyID --How to store select top 1?
,replace(LTRIM(RTRIM(AP.UserNameWebsite)), '\', '') AS username
,replace(LTRIM(RTRIM(AP.FirstName)), '\', '') + N' ' + replace(LTRIM(RTRIM(AP.LastName)), '\', '') AS fullName
,LTRIM(RTRIM(AP.EmailAddress)) AS email
,LTRIM(RTRIM(AP.Phone1)) AS phone1
,LTRIM(RTRIM(AP.Phone2)) AS phone2
,LTRIM(RTRIM(AP.GreenSolution)) AS greenSolution
,CASE
WHEN UserType = 'AM'
THEN 1
ELSE 0
END AS producer
FROM DEV01_DataExchange.[DuckCreek].[fpmAgentsProfile] AP
Inner Join [DUCKCREEK_DEV].[DEV01_DuckCreek_Consolidated].[dbo].Agency DCA
on AP.AgencyID = DCA.Reference
WHERE TransType = 'A' AND DC_LastModifiedDate IS NULL AND DCA.Reference is NOT NULL
Your question is a bit vague, but the answer is cross apply:
FROM DEV01_DataExchange.[DuckCreek].[fpmAgentsProfile] AP CROSS APPLY
(SELECT TOP (1) DCA.*
FROM [DUCKCREEK_DEV].[DEV01_DuckCreek_Consolidated].[dbo].Agency DCA
WHERE AP.AgencyID = DCA.Reference
) DCA
WHERE TransType = 'A' AND DC_LastModifiedDate IS NULL AND DCA.Reference is NOT NULL;
Normally an ORDER BY clause would be used. Perhaps ORDER BY DCA.AgencyID DESC? However, if there is a column called AgencyID, I'm surprised it is not being used for the alignment to AP.
Also, some of the WHERE conditions might belong in the subquery.
You can use a Cross Apply instead of the Join:
SELECT AP.ID
,DCA.AgencyID as agencyID
,replace(LTRIM(RTRIM(AP.UserNameWebsite)), '\', '') AS username
,replace(LTRIM(RTRIM(AP.FirstName)), '\', '') + N' ' + replace(LTRIM(RTRIM(AP.LastName)), '\', '') AS fullName
,LTRIM(RTRIM(AP.EmailAddress)) AS email
,LTRIM(RTRIM(AP.Phone1)) AS phone1
,LTRIM(RTRIM(AP.Phone2)) AS phone2
,LTRIM(RTRIM(AP.GreenSolution)) AS greenSolution
,CASE
WHEN UserType = 'AM'
THEN 1
ELSE 0
END AS producer
FROM DEV01_DataExchange.[DuckCreek].[fpmAgentsProfile] AP
Cross Apply
(
Select top 1 AG.*
From [DUCKCREEK_DEV].[DEV01_DuckCreek_Consolidated].[dbo].Agency AG
where AG.Reference = AP.AgencyID
) DCA
WHERE TransType = 'A' AND DC_LastModifiedDate IS NULL AND DCA.Reference is NOT NULL

pyspark sql jdbc error - Incorrect syntax near the keyword 'SET'

Following is the SQL Sample which Im trying to run, but its is giving me error - ***.jdbc.SQLServerException: Incorrect syntax near the keyword 'SET'
tp_temp = """
SET NOCOUNT ON
declare #lp_dt dt = (select max(pt_dt) from [DB_TABLE].[db].[DATA] where p_type='WSD')
declare #L_dte tb (pt, pt_type char(1))
insert into #L_dte SELECT pt_dt, pt_type
FROM from [DB_TABLE].[db].[DATA]
where (PT_Type = 'Z' and Month(pt_dt) in (1,4,7,10) and pt_dt > '2017 Sep 1') or (PT_Type = 'K' and pt_dt = #lp_dt )
group by pt_dt, PT_Type
order by pt_dt
SELECT z_id_alt, z_id, z_Status_Alt, c_Gp_CCD, Gender, Age, ctk as CTK_Red, CAT_Title, temp_Group, Comp_price, terminator_action_alt AS Terminator_Action, v_pt.PT_Dt,CASE
WHEN COALESCE([Acb_Indicator], '') = ''
THEN ('No')
ELSE ('Yes')
END AS [Is Acb],
COALESCE(nullif([Region_Desc_NEWCO_Original], ''), Region_Desc_NEWCO) AS Region_Desc_NEWCO,
COALESCE(nullif([POG3_Desc_Original], ''), POG3_Desc) AS POG3_Desc,
COALESCE(nullif([POG9_Desc_Original], ''), POG9_Desc) AS POG9_Desc, COALESCE(nullif(BSD_Function, ''), OrgUnit_Function_L2_NEWCO) as OrgUnit_Function_L2_NEWCO, CASE
WHEN COALESCE(nullif([POG3_Desc_Original], ''), POG3_Desc) IN (
SELECT [POG_Desc]
FROM [DB_FREE].[dbz].[Free_dom]
WHERE POG_Type = 'POG3'
)
OR COALESCE(nullif([POG9_Desc_Original], ''), POG9_Desc) IN (
SELECT [POG_Desc]
FROM [DB_FREE].[dbz].[Free_dom]
WHERE POG_Type = 'POG9'
)
THEN 'Yes'
ELSE 'No'
END AS [Restricted_Home], Zero) AS Booring
FROM (SELECT * FROM [DB_FREE].[dbz].[Free_dom] WHERE noshow = 'N' AND E_Type <> 'SubConsole') as v_pt
INNER JOIN #l_pt_dt as pt_dt on v_pt.pt_dt = pt_dt.pt_dt and v_pt.pt_type = pt_dt.pt_type
LEFT OUTER JOIN [DB_TABLE].[db].[DATA] AS o_p ON o_p.[u_number] = v_pt.ete_idg """
df_temp= spark.read.jdbc(url=jdbcUrl, table=tp_temp, properties=connectionProperties)
For simple SQL starting with Select command it works but for code starting with SET or WITH it throws errors, please let me know how I can create a table from this SQL code in pyspark dataframe

How to specify multiple values in when using case statement in sql server

I have the following table
Id Number TypeOfChange
1 2X Scope,Cost,Schedule,EVM,PA
2 3x Scope,Cost
Expected output:
Id Number TypeOfChange Scope Cost Schedule EVM PA
1 2X Scope,Cost,Schedule,EVM,PA X X X X X
2 3x Scope,Cost X X
I try the following script but its not working
SELECT
Id,
Number,
TypeOfChange,
Scope = CASE
WHEN TypeOfChange = 'Scope' THEN 'X'
ELSE '' END,
Cost = CASE
WHEN TypeOfChange = 'Cost' THEN 'X'
ELSE '' END,
Schedule = CASE
WHEN TypeOfChange = 'Schedule' THEN 'X'
ELSE '' END,
EVM = CASE
WHEN TypeOfChange = 'EVM' THEN 'X'
ELSE '' END,
PA = CASE
WHEN TypeOfChange = 'PA' THEN 'X'
ELSE '' END
FROM A
Use Like operator.
SELECT
Id,
Number,
TypeOfChange,
Scope = CASE
WHEN TypeOfChange Like '%Scope%' THEN 'X'
ELSE '' END,
Cost = CASE
WHEN TypeOfChange Like '%Cost%' THEN 'X'
ELSE '' END,
Schedule = CASE
WHEN TypeOfChange Like '%Schedule%' THEN 'X'
ELSE '' END,
EVM = CASE
WHEN TypeOfChange Like '%EVM%' THEN 'X'
ELSE '' END,
PA = CASE
WHEN TypeOfChange Like '%PA%' THEN 'X'
ELSE '' END
FROM A
Example:
we can try charindex or patindex
SELECT
Id,
Number,
TypeOfChange,
Scope = CASE
WHEN CHARINDEX('Scope',TypeOfChange)>0 THEN 'X'
ELSE '' END,
Cost = CASE
WHEN CHARINDEX('Cost',TypeOfChange)>0 THEN 'X'
ELSE '' END,
Schedule = CASE
WHEN CHARINDEX('Schedule',TypeOfChange)>0 THEN 'X'
ELSE '' END,
EVM = CASE
WHEN CHARINDEX('EVM',TypeOfChange)>0 THEN 'X'
ELSE '' END,
PA = CASE
WHEN CHARINDEX('PA',TypeOfChange)>0 THEN 'X'
ELSE '' END
FROM #AA
output
Id Number TypeOfChange Scope Cost Schedule EVM PA
1 2X Scope,Cost,Schedule,EVM,PA X X X X X
2 3x Scope,Cost X X
If TypeOfChange is a dynamic value, you may want to go the dynamic route.
select * into [T1] from
(values (1, '2X', 'Scope,Cost,Schedule,EVM,PA'), (2, '3x', 'Scope,Cost'), (3, '4x', 'someOtherType')) t(Id, Number, TypeOfChange)
--typeOfChange into column list
Declare #SQL varchar(max) = Stuff((
SELECT distinct ',' + QuoteName(LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))))
FROM ( SELECT CAST('<XMLRoot><RowData>' + REPLACE(TypeOfChange,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x
FROM [T1]) t CROSS APPLY x.nodes('/XMLRoot/RowData')m(n)
Order by 1 For XML Path('')),1,1,'')
Select #SQL = '
Select [Id],[Number], [TypeOfChange],' + #SQL + '
From (
SELECT Id, Number, TypeOfChange,
LTRIM(RTRIM(m.n.value(''.[1]'',''varchar(8000)''))) AS [Type], ''X'' as Value
FROM ( SELECT Id, Number, TypeOfChange, CAST(''<XMLRoot><RowData>'' + REPLACE(TypeOfChange,'','',''</RowData><RowData>'') + ''</RowData></XMLRoot>'' AS XML) AS x
FROM [T1]) t CROSS APPLY x.nodes(''/XMLRoot/RowData'')m(n)
) A
Pivot (max(Value) For [Type] in (' + #SQL + ') ) pvt'
Exec(#SQL);
Alternatively you may want to define your Types in a lookup table
select * into [Types] from
(values (1, 'Scope'), (2, 'Cost'), (3, 'Schedule'), (4, 'EVM'), (5, 'PA'), (6, 'someOtherType')) a (Id, TypeOfChange)
Then change the above --typeOfChange into column.. block like this:
--typeOfChange into column list
Declare #SQL varchar(max) = Stuff((
SELECT distinct ',' + QuoteName(TypeOfChange)
FROM [Types]
Order by 1 For XML Path('')),1,1,'')
I think, using LIKE is wrong approach. Especcialy in cases, when one of your strings become f.e."Periscope". You will get false positives.
Try to create user defined function to split strs:
CREATE FUNCTION [dbo].[str__split](
#str NVARCHAR(MAX)
,#delimiter NVARCHAR(MAX)
)
RETURNS #split TABLE(
[str] NVARCHAR(MAX)
)
AS
BEGIN
INSERT INTO #split(
[str]
)
SELECT
[X].[C].[value]('(./text())[1]', 'nvarchar(4000)')
FROM
(
SELECT
[X] = CONVERT(XML, '<i>' + REPLACE(#str, #delimiter, '</i><i>') + '</i>').query('.')
) AS [A]
CROSS APPLY
[X].[nodes]('i') AS [X]([C]);
RETURN;
END
And then use query:
SELECT
[t].*
,[Scope] = CASE WHEN [t2].[Scope] IS NULL THEN NULL ELSE 'X' END
,[Cost] = CASE WHEN [t2].[Cost] IS NULL THEN NULL ELSE 'X' END
,[Schedule] = CASE WHEN [t2].[Schedule] IS NULL THEN NULL ELSE 'X' END
,[EVM] = CASE WHEN [t2].[EVM] IS NULL THEN NULL ELSE 'X' END
,[PA] = CASE WHEN [t2].[PA] IS NULL THEN NULL ELSE 'X' END
FROM
[your table] AS [t]
OUTER APPLY
(
SELECT * FROM (SELECT [str] from [dbo].[str__split]([TypeOfChange], ',')) AS [d]
PIVOT
(MAX([str]) FOR [str] IN ([Scope], [Cost], [Schedule], [EVM], [PA])) AS [piv]
) AS [t2]

SQL Server 2014 - Case statement not exiting

I am having trouble writing a query to meet the following requirement. One point if Cust_3_3_a through Cust_3_3_c is selected, or Cust_3_3_f through Cust_3_3_h is selected, or Cust_3_4_ is selected; Zero points if Cust_3_3_e is selected and Cust_3_4_ is not selected with value '-'. Selected essentially means a the field has a value of a, b, c, etc.
Here is my test data and query. I would expect with 'Cust_3_4_' set to '-', that 0 should return but 1 returns instead. Is SQL not exiting the case when it hits 0 since the following check would return 1? Thanks in advance.
declare #test table (QuestionKey nvarchar(100), ResponseValue nvarchar(100))
insert into #test (QuestionKey, ResponseValue)
values
('Cust_3_3_a', ''), ('Cust_3_4_', '-'),
('Cust_3_3_b', ''),
('Cust_3_3_c', ''),
('Cust_3_3_e', 'a'),
('Cust_3_3_f', ''),
('Cust_3_3_g', ''),
('Cust_3_3_h', '')
select
max(case
when (
(t.questionkey = 'Cust_3_3_e' AND nullif(t.ResponseValue, '') IS NOT NULL)
and (t.questionkey = 'Cust_3_4_' AND nullif(t.ResponseValue, '') != '-')
) then 1
when (
(t.questionkey = 'Cust_3_3_e' AND nullif(t.ResponseValue, '') IS NOT NULL)
and (t.questionkey = 'Cust_3_4_' AND nullif(t.ResponseValue, '') = '-')
) then 0
when (
t.questionkey BETWEEN 'Cust_3_3_a' AND 'Cust_3_3_c'
OR t.questionkey BETWEEN 'Cust_3_3_f' AND 'Cust_3_3_h'
OR t.questionkey = 'Cust_3_4_'
) and nullif(t.ResponseValue, '') IS NOT NULL then 1
else 0
end) as test1
from #test t
Not sure what you want but I think you are confused with how case statement works. In order for you to return 0 for Cust_3_4_ where ResponseValue != '-', you need to have an actual row with QuestionKey = Cust_3_4_ and ResponseValue != '-' in your table (which you do not have in the above data set)
Also, you have applied MAX function outside your case so it will return you the maximum value 1 if any of the case condition returns 1. If you want the final result 0, you need to use MIN instead BUT please be aware that the 0 will be returned because of the following condition on Cust_3_3_e. Cust_3_4_ will have nothing to do with the 0
declare #test table (QuestionKey nvarchar(100), ResponseValue nvarchar(100))
insert into #test (QuestionKey, ResponseValue)
values
('Cust_3_3_a', ''), ('Cust_3_4_', '-'),
('Cust_3_3_b', ''),
('Cust_3_3_c', ''),
('Cust_3_3_e', 'a'),
('Cust_3_3_f', ''),
('Cust_3_3_g', ''),
('Cust_3_3_h', '')
select * from #test
order by 1 asc
select *,case when QuestionKey IN ('Cust_3_3_a','Cust_3_3_b','Cust_3_3_c') THEN 1
when QuestionKey = 'Cust_3_3_e' THEN 0
when QuestionKey IN ('Cust_3_3_f','Cust_3_3_g','Cust_3_3_h') THEN 1
when QuestionKey = 'Cust_3_4_' AND ResponseValue = '-' THEN 1
when QuestionKey = 'Cust_3_4_' AND ResponseValue <> '-' THEN 0
end test1
from #test

Check null or empty data from three columns in SQL Server

I have a table with three columns and I want to check Null or Empty data from the columns either its is Imp or Main or Comp.
I am using the following query:
SELECT Imp,Main,Comp
FROM Items_tbl
WHERE Contributor = 37
AND NULLIF(Imp, '') IS NULL
AND NULLIF(Main, '') IS NULL
AND NULLIF(Comp, '') IS NULL;
So if you want to COUNT the rows you could just do the following:
SELECT COUNT(*)
FROM Items_tbl
WHERE Contributor=37
AND NULLIF(Imp, '') IS NULL
AND NULLIF(Main, '') IS NULL
AND NULLIF(Comp, '') IS NULL;
Or if you only need one of those columns to be NULL:
SELECT COUNT(*)
FROM Items_tbl
WHERE Contributor=37
AND (NULLIF(Imp, '') IS NULL
OR NULLIF(Main, '') IS NULL
OR NULLIF(Comp, '') IS NULL
);
Based on your comment regarding needing a count...
SELECT Count(*)
FROM Items_tbl
WHERE Contributor=37 and ISNULL(Imp, '') = ''
and ISNULL(Main, '') = ''
and ISNULL(Comp, '') = '' ;
Well I am not sure if I have understood the question correctly, but if you want all the rows where the 3 columns is either NULL/empty, you could try this :
SELECT ID, Contributor,
Imp,
Main,
Comp
FROM Items_tbl
WHERE Contributor = 37
AND (Imp IS NULL OR Imp = '')
AND (Main IS NULL OR Main = '')
AND (Comp IS NULL OR Comp = '')
You can see this here ->SQL fiddle
Note that for this query either all the 3 columns in question should either be all NULL or all empty.
In case, you want all the rows where even one of the aforementioned columns is NULL/empty, you could use a `UNION' to get this as follows :
SELECT ID, Contributor,
Imp,
Main,
Comp
FROM Items_tbl
WHERE Contributor = 37
AND (Imp IS NULL OR Imp = '')
AND (Main IS NULL OR Main = '')
AND (Comp IS NULL OR Comp = '')
UNION
SELECT ID, Contributor,
Imp,
Main,
Comp
FROM Items_tbl
WHERE Contributor = 37
AND (Imp IS NULL)
OR (Main IS NULL)
OR (Comp IS NULL)
See this here -> SQL fiddle
Hope this helps!!!
Try this.
Edit:
SELECT Imp,Main,Comp
FROM Items_tbl
WHERE Contributor=37 AND COALESCE(NULLIF(ISNULL(Imp,''),''),NULLIF(ISNULL(Main,''),''),NULLIF(ISNULL(Comp,''),'')) is NULL