Is it possible to refactor this statement to remove the subquery? - tsql

I'm trying to take data from one column, MyTable.SSN, and copy it to another in the same table, MyTable.SSNWithDashes, just formatted differently. If MyTable.SSN doesn't have exactly 9 digits, I don't care to process it at all.
I've tried this:
IF( SELECT LEN( [SSN] ) FROM [MyTable] ) = 9
UPDATE [MyTable] SET [SSNWithDashes] = LEFT( [SSN], 3 ) + '-' + SUBSTRING( [SSN], 4, 2 ) + '-' + RIGHT( [SSN], 4 )
ELSE
UPDATE [MyTable] SET [SSNWithDashes] = NULL
While this works, it throws an error:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
While I do understand what the warning is saying, I'm not really sure how to go about this differently.
How can I refactor this to remove that warning (and perhaps read a little cleaner)?

UPDATE dbo.[MyTable]
SET [SSNWithDashes] = CASE
WHEN LEN(SSN) = 9 THEN
LEFT([SSN],3) + '-' + SUBSTRING([SSN],4,2) + '-' + RIGHT([SSN],4)
ELSE NULL
END;

Assuming your SSNWithDashes is already NULL then
UPDATE dbo.[MyTable]
SET [SSNWithDashes] = LEFT([SSN],3) + '-' + SUBSTRING([SSN],4,2) + '-' + RIGHT([SSN],4)
WHERE LEN(SSN) = 9
Every other rows remain NULL

Related

replace elements in a 2d array

Given a 2d array
select (ARRAY[[1,2,3], [4,0,0], [7,8,9]]);
{{1,2,3},{4,0,0},{7,8,9}}
Is there a way to replace the slice at [2:2][2:] (the {{0,0}}) with values 5 and 6? array_replace replaces a specific value so I'm not sure how to approach this.
I believe it's more readable to code a function in plpgsql. However, a pure SQL solution also exists:
select (
select array_agg(inner_array order by outer_index)
from (
select outer_index,
array_agg(
case
when outer_index = 2 and inner_index = 2 then 5
when outer_index = 2 and inner_index = 3 then 6
else item
end
order by inner_index
) inner_array
from (
select item,
1 + (n - 1) % array_length(a, 1) inner_index,
1 + (n - 1) / array_length(a, 2) outer_index
from
unnest(a) with ordinality x (item, n)
) _
group by outer_index
)_
)
from (
select (ARRAY[[1,2,3], [4,0,0], [7,8,9]]) a
)_;

UPDATE table via join in SQL

I am trying to normalize my tables to make the db more efficient.
To do this I have removed several columns from a table that I was updating several columns on.
Here is the original query when all the columns were in the table:
UPDATE myActDataBaselDataTable
set [Correct Arrears 2]=(case when [Maturity Date]='' then 0 else datediff(d,convert(datetime,#DataDate, 102),convert(datetime,[Maturity Date],102)) end)
from myActDataBaselDataTable
Now I have removed [Maturity Date] from the table myActDataBaselDataTable and it's necessary to retrieve that column from the base reference table ACTData, where it is called Mat.
In my table myActDataBaselDataTable the Account number field is a concatenation of 3 fields in ACTData, thus
myActDataBaselDataTable.[Account No]=ac.[Unit] + ' ' + ac.[ACNo] + ' ' + ac.[Suffix]
(where ac is the alias for ACTData)
So, having looked at the answers given elsewhere on SO (such as 1604091: update-a-table-using-join-in-sql-server), I tried to modify this particular update statement as below, but I cannot get it right:
UPDATE myActDataBaselDataTable
set dt.[Correct Arrears 2]=(
case when ac.[Mat]=''
then 0
else datediff(d,convert(datetime,'2014-04-30', 102),convert(datetime,ac.[Mat],102))
end)
from ACTData ac
inner join myActDataBaselDataTable dt
ON dt.[Account No]=ac.[Unit] + ' ' + ac.[ACNo] + ' ' + ac.[Suffix]
I either get an Incorrect syntax near 'From' error, or The multi-part identifier "dt.Correct Arrears 2" could not be bound.
I'd be grateful for any guidance on how to get this right, or suugestiopns about how to do it better.
thanks
EDIT:
BTW, when I run the below as a SELECT it returns data with no errors:
select case when [ac].[Mat]=''
then 0
else datediff(d,convert(datetime,'2014-04-30', 102),convert(datetime,[ac].[Mat],102))
end
from ACTData ac
inner join myActDataBaselDataTable dt
ON dt.[Account No]=ac.[Unit] + ' ' + ac.[ACNo] + ' ' + ac.[Suffix]
In a join update, update the alias
update dt
What is confusing is that in later versions of SQL you don't need to use the alias in the update line

Uniquename function in mdx script

I really need your help.
For a SSRS report, I have this mdx script:
select
{[Geographie].[Commune].[AHUY], [Geographie].[Commune].[BRETENIERE]} on columns
,{[Activite].[Branche].&[B], [Activite].[Branche].&[C]} on rows
from [ACSEL2]
where ([Measures].[CATTC], [Perimetre].[Perimetre].&[2], [Temps].[Annee].&[2006])
Please, I need to have the uniquename for the members that I have in columns
({[Geographie].[Commune].[AHUY], [Geographie].[Commune].[BRETENIERE]})
Please Can U help me to write this mdx script ?
Lidou
Declare a member using With statement, like this:
WITH MEMBER [Measures].[UniqueName] as [Geographie].[Commune].CurrentMember.UniqueName
Select
--Your select here
More details on CurrentMember
WITH
-- Geography metadata
MEMBER [Measures].[Geographie]
AS StrToValue ( #SelectionGeographie + ".Hierarchy.Currentmember.Uniquename" )
MEMBER [Measures].[Geographie_Label]
AS StrToValue( #SelectionGeographie + ".Hierarchy.CurrentMember.Member_Caption" )
SELECT NON EMPTY {
[Measures].[Geographie],
[Measures].[Geographie_Label],
[Measures].[11 VA]
} ON COLUMNS,
( STRTOSET ( "{" + #SelectionGeographie + "}") ,
STRTOSET ("{" + #SelectionActivite + "}" ))
ON ROWS
FROM [MyCube]
WHERE STRTOTUPLE ( "(" +#Annee + "," + #Perimetre + ")" )

How to add logic to my SQL query to include/exclude search parameters?

Using SQL Server 2008R2, I have here is a simple query:
SELECT *
FROM ItemData
WHERE FREETEXT(Title, '"' + #OriginalSearchTerm + '"')
AND ( WebsiteID=#WebsiteID AND GeoCity = #GeoCity AND GeoState = #GeoState )
ORDER BY ItemListID DESC
This is all fine when there is a valid value for #GeoCity and #GeoState. However there will be scenarios where #GeoCity = -1 and/or #GeoState = -1.
I would rather not write entire separate queries for these cases, although this would work just fine.
How can I optimize the current query to do just this?
Thanks.
-- This might be more efficient as OR statement executes block for each OR statement.
SELECT *
FROM ItemData
WHERE FREETEXT(Title, '"' + #OriginalSearchTerm + '"')
AND ( WebsiteID=#WebsiteID AND
(GeoCity = ISNULL(#GeoCity,-1)) AND
(GeoState = ISNULL(GeoState,-1))
ORDER BY ItemListID DESC
I'm not sure what you want the query to do when #GeoCity = -1 and/or #GeoState = -1. Assuming you want to exclude the GeoCity = #GeoCity and/or GeoState = #GeoState conditions in that case, here's the query:
SELECT *
FROM ItemData
WHERE FREETEXT(Title, '"' + #OriginalSearchTerm + '"')
AND ( WebsiteID=#WebsiteID AND
(#GeoCity = -1 OR GeoCity = #GeoCity) AND
(#GeoState = -1 OR GeoState = #GeoState) )
ORDER BY ItemListID DESC

How do you concatenate strings inside of a CONTAINS in SQL Server 2008?

SQL Server 2008 is telling me that it doesn't like the "+" in the CONTAINS.
Not sure what I'm doing wrong here.
INSERT INTO dbo.tblImportTitles
(
ImportTitleGUID,
UserGUID,
TitleName,
TitleGUID
)
SELECT
ImportTitleGUID = T.Item.value('#ImportTitleGUID', 'uniqueidentifier'),
UserGUID = T.Item.value('#UserGUID', 'uniqueidentifier'),
TitleName = T.Item.value('#TitleName', 'varchar(255)'),
TitleGUID =
CASE
WHEN (SELECT TOP(2) COUNT(TitleGUID) FROM dbo.tblTitles WHERE CONTAINS(Title, '''' + T.Item.value('#TitleName', 'varchar(255)') + '''')) = 1
THEN (SELECT TitleGUID FROM dbo.tblTitles WHERE CONTAINS(Title,'''' + T.Item.value('#TitleName', 'varchar(255)') + ''''))
ELSE NULL
END
FROM #ImportTitlesInsertXml.nodes('BatchTitles/BTitle') AS T(Item)
Update
I'v decided to move this to a scalar function.
It was a lot easier to handle the code that way.
use QUOTENAME(#VARIABLE,'''') the + is not your problem.