Better method for concatenating columns into a single column - sql-server

Please consider the following table that holds address details for people:
DECLARE #tbl TABLE
(
userId int IDENTITY(1,1),
address1 nvarchar(100),
address2 nvarchar(100),
address3 nvarchar(100),
addressTown nvarchar(100),
addressCounty nvarchar(100),
addressPostCode nvarchar(10)
);
INSERT INTO
#tbl (address1, address2, address3, addressTown, addressCounty, addressPostCode)
VALUES
('1 Some Road', 'High Hill', 'Battersea', 'London', NULL, 'SW1 2AB'),
('54 Main Street', 'Lowville', NULL, 'Sometown', 'Cumbria', 'AB12 3BA');
SELECT * FROM #tbl;
The output shows this:
userId address1 address2 address3 addressTown addressCounty addressPostCode
----------- --------------- -------------- ------------- ---------------- ------------- ---------------
1 1 Some Road High Hill Battersea London NULL SW1 2AB
2 54 Main Street Lowville NULL Sometown Cumbria AB12 3BA
However, I'd like to concatenate all of the address fields into a single field for the purpose of this statement, so that the results appear as follows:
userId Address
----------- --------------------
1 1 Some Road
High Hill
Battersea
London
SW1 2AB
2 54 Main Street
Lowville
Sometown
Cumbria
AB12 3BA
Please note that this is NOT the same problem as concatenating rows in a single column (using XML etc)!
I have done this using the following approach, but it seems like a whole lot of code for such a small task:
SELECT
userId,
CASE WHEN address1 IS NOT NULL THEN
address1 + CHAR(13) + CHAR(10)
ELSE ''
END +
CASE WHEN address2 IS NOT NULL THEN
address2 + CHAR(13) + CHAR(10)
ELSE ''
END +
CASE WHEN address3 IS NOT NULL THEN
address3 + CHAR(13) + CHAR(10)
ELSE ''
END +
CASE WHEN addressTown IS NOT NULL THEN
addressTown + CHAR(13) + CHAR(10)
ELSE ''
END +
CASE WHEN addressCounty IS NOT NULL THEN
addressCounty + CHAR(13) + CHAR(10)
ELSE ''
END +
CASE WHEN addressPostCode IS NOT NULL THEN
addressPostCode + CHAR(13) + CHAR(10)
ELSE ''
END as [Address]
FROM
#tbl
Is there a better/faster/more recommended way to achieve this?

You can use ISNULL (or COALESCE if you prefer)
select
ISNULL(Address1 + char(13) + char(10), '') +
ISNULL(Address2 + char(13) + char(10), '') + ...
from #tbl
(Because NULL + something is still NULL)

Thanks to #podiluska's input, here is the final answer that also ensures NULLs are returned if the entire concatenated address is still NULL:
SELECT
userId,
NULLIF(ISNULL(address1 + CHAR(13) + CHAR(10), '') +
ISNULL(address2 + CHAR(13) + CHAR(10), '') +
ISNULL(address3 + CHAR(13) + CHAR(10), '') +
ISNULL(addressTown + CHAR(13) + CHAR(10), '') +
ISNULL(addressCounty + CHAR(13) + CHAR(10), '') +
ISNULL(addressPostCode + CHAR(13) + CHAR(10), ''), '') as [Address]
FROM
#tbl;

Related

Why varchar size affects query performance?

I have a query that generates a JSON string. It looks something like this, where #Names is varchar(max):
DECLARE #Names VARCHAR(MAX)
IF OBJECT_ID('tempdb..#temp') IS NOT NULL DROP TABLE #temp
create table #temp
(
col1 varchar(100),
col2 varchar(100),
col3 varchar(100),
col4 varchar(100),
col5 varchar(100)
)
declare #count int = 1
WHILE #count <= 600
BEGIN
insert into #temp select 'stuff', 'more stuff', 'even more stuff', 'not enough stuff', 'just the right stuff'
select #count = #count + 1
END
;with cte as
(
select Col1, Col2,col3, col4, col5 from #temp
)
select #Names = COALESCE(#Names + ', ', '') + '{"type": "Feature", ' +
'"properties": {' +
'"Name": "' + cte.Col1 + '",' +
'"Category": "' + cte.Col2 + '",' +
'"UserId": "' + cte.col3 + '",' +
'"Other": "' + cte.col4 + '",' +
'"lat": ' + cte.col5 + ',' +
'"long": ' + cte.col5 + ',' +
'"MyDate": "' + cte.col5 + '",' +
'"Icon": "' + 'icons/MyIcon.svg' + '"' +
'}' +
',"geometry": {"type": "Point","coordinates": [' + cte.col1 + ', ' + cte.col1 + ']}}'
from cte
declare #header varchar(500)
select #header =
'{ ' +
'"type": "FeatureCollection", ' +
'"features": [ '
declare #footer varchar(100) = '] ' +
'} '
select #header + #Names + #footer as 'json'
The complete query takes about 15 seconds to run, while the query within the cte takes less than one second. The problem was with building the string outside the cte.
I ended up changing #Names to varchar(5000), and the performance dramatically improved from 11 seconds to less than a second.
Why would this size change in #Names have such an improvement in the query? The cte query returns 600 rows.

How to combine FirstName, MiddleName, LastName, comma and suffix in SQL Server?

I am trying to combine FirstName, MiddleName, LastName then a comma and suffix.
An example here describes this:
Sno. FirstName MiddleName LastName Suffix Result
---------------------------------------------------------------
1. ROBERT NULL SMALLWOOD NULL ROBERT SMALLWOOD
2. KIRK NULL ROBERTS MR KIRK ROBERTS, MR
3. WILLIAM DARRELL WATTENBARGER Jr. WILLIAM DARRELL WATTENBARGER, MR
If there is no Suffix, then comma (,) should not be appended also there should be only one space after every column.
So far I tried
REPLACE(RTRIM(Coalesce(FirstName + ' ', '') + Coalesce(MiddleName + ' ', '') + Coalesce(LastName + ' ', '') + Coalesce(SuffixId + ' ', '')),' ',' ')
Now how should I add a comma before suffix in case if it only exists without using case.
Thanks
You can use CONCAT:
SELECT CONCAT(FirstName,' ',MiddleName + ' ' ,LastName,', '+NULLIF(Suffix,'')) [Result]
FROM dbo.YourTable;
Use ISNULL:
SELECT ISNULL(FirstName + ' ', '') + ISNULL(MiddleName + ' ', '') + ISNULL(LastName + ' ', '') + ISNULL(', ' + SuffixId, '')
FROM My_Table_Name
This is the solution I came up with, please try and see if that worked for you.
create table #FullNameCalculation
(
Sno int not null,
FirstName varchar(10),
MiddleName varchar(10),
LastName varchar(15),
Suffix varchar(5)
)
insert into #FullNameCalculation
(Sno,FirstName,MiddleName,LastName,Suffix)
values
(1, 'ROBERT', NULL,'SMALLWOOD', NULL),
(2, 'KIRK', NULL, 'ROBERTS', 'MR'),
(3,'WILLIAM', 'DARRELL', 'WATTENBARGER', 'JR.'),
(4,NULL,'BARBER','SINK','MS'),
(5,NULL,NULL,'SANDERS','MRS.'),
(6,'SARA',' D','WILLIAMS ',' MS');
SELECT * FROM #FullNameCalculation;
SELECT *,
RTRIM(LTRIM(CONCAT(RTRIM(LTRIM(FirstName)),' ',
RTRIM(LTRIM(MiddleName)),' ',
RTRIM(LTRIM(LastName)),
iif(RTRIM(LTRIM(Suffix)) IS NULL OR RTRIM(LTRIM(Suffix))='','',', '+RTRIM(LTRIM(Suffix)))))) AS FullName
FROM #FullNameCalculation;
I wanted to do something similar and I used COALESCE like OP. Using the suggestion from Mark Adelsberger my query looked like this:
SELECT
RTrim(Coalesce(FirstName + ' ', '')
+ Coalesce(MiddleName + ' ', '')
+ Coalesce(LastName + ' ', '')
+ Coalesce(', ' + Suffix, '')) FullName
FROM dbo.YourTable

Select a columns name as another tables row data in SQL Server

I have a table say Configs in which I have the column names
id | Name
-------------
1 | Fruits
2 | Vegetables
3 | Pulses
I have another table say Details
id |Field1 | Field2| Field3 | Active | Mandatory
-------------------------------------------------
1 |Apple |Potato |Red gram | 1 |0
2 |Mango |Peas |Chick Peas| 0 |0
I need field1, field2, field3 to be selected as the name of 1st table
eg.
select
id,
Field1 as Fruits,
Field2 as Vegetables,
Field3 as pulses,
Active,
Mandatory
From
Details
How do I do it?
declare #sql nvarchar(max)
select #sql = isnull(#sql + ',' ,'')
+ N'Field' + convert(varchar(10), id) + ' as ' + quotename(Name)
from Config
-- Form the dynamic SQL
select #sql = 'SELECT id,'
+ #sql
+ ',Active, Mandatory '
+ 'FROM Details'
-- Print to verify
print #sql
-- Execute it
exec sp_executesql #sql
Something like these perhaps:
Method #1
IF OBJECT_ID(N'Configs', N'U') IS NULL
CREATE TABLE Configs(ID INT, Name NVARCHAR(25));
ELSE
TRUNCATE TABLE Configs
INSERT INTO Configs VALUES(1, 'Fruits'), (2, 'Vegetables'), (3, 'Pulses');
IF OBJECT_ID(N'Configs', N'U') IS NULL
CREATE TABLE Details(ID INT, Field1 NVARCHAR(25), Field2 NVARCHAR(25), Field3 NVARCHAR(25)
,Active BIT, Mandatory BIT);
ELSE
TRUNCATE TABLE Details
INSERT INTO Details VALUES(1, 'Apples', 'Potato', 'Red Gram', 1, 0)
,(2, 'Mango', 'Peas', 'Chick Peas', 0, 0);
DECLARE #Sql NVARCHAR(MAX);
SELECT #Sql = 'SELECT id,' + CHAR(13)
+ ' [Field1] as ' + QUOTENAME((SELECT Name FROM Configs WHERE ID = 1)) +',' + CHAR(13)
+ ' [Field2] as ' + QUOTENAME((SELECT Name FROM Configs WHERE ID = 2)) +',' + CHAR(13)
+ ' [Field3] as ' + QUOTENAME((SELECT Name FROM Configs WHERE ID = 3)) +',' + CHAR(13)
+ ' Active,' + CHAR(13)
+ ' Mandatory ' + CHAR(13)
+ 'From Details' + CHAR(13);
PRINT #Sql;
EXEC sp_executesql #Sql;
Method #2
IF OBJECT_ID(N'Configs', N'U') IS NULL
CREATE TABLE Configs(ID INT, Name NVARCHAR(25));
ELSE
TRUNCATE TABLE Configs
INSERT INTO Configs VALUES(1, 'Fruits'), (2, 'Vegetables'), (3, 'Pulses');
IF OBJECT_ID(N'Configs', N'U') IS NULL
CREATE TABLE Details(ID INT, Field1 NVARCHAR(25), Field2 NVARCHAR(25), Field3 NVARCHAR(25)
,Active BIT, Mandatory BIT);
ELSE
TRUNCATE TABLE Details
INSERT INTO Details VALUES(1, 'Apples', 'Potato', 'Red Gram', 1, 0)
,(2, 'Mango', 'Peas', 'Chick Peas', 0, 0);
DECLARE #Sql NVARCHAR(MAX) = 'SELECT' + CHAR(13) + CHAR(9) + 'ID' + CHAR(13);
SELECT
#Sql += STUFF((
SELECT
CHAR(9) + ',' + QUOTENAME('Field' + LTRIM(STR(ROW_NUMBER()OVER(ORDER BY ID)))) + ' AS ' + QUOTENAME(Name) + CHAR(13)
FROM
Configs
FOR XML PATH(''), type).value('.', 'nvarchar(max)'), 1, 0, '');
SELECT
#Sql += CHAR(9) +',Active' + CHAR(13)
+ CHAR(9) +',Mandatory ' + CHAR(13)
+ 'From Details' + CHAR(13);
PRINT #Sql;
EXEC sp_executesql #Sql;

Subquery inside a view is not working corectly

Hey I am creating view to be used in FastReport(ReportingSoftware) and I have a sub-query in the form of a scalar-Valued Function inside this to pull together the full address of a property, Though it is bringing back the error Subquery returned more than 1 value and im not sure why, i have used something similar to this in the past cant seem to figure out the issue.
Here is my View Code
SELECT TOP (100) PERCENT dbo.PropertyMaster.PropertyID,
dbo.Lookup_PropertyManager.Description, dbo.Lookup_PropertyManager.Email,
dbo.GetFullAddress(dbo.PropertyMaster.PropertyID) AS FullAddress,
dbo.Tenants.TenantID, dbo.Tenants.LeaseID,
dbo.Tenants.TenantForeName + ' ' + dbo.Tenants.TenantSurname AS FullName,
dbo.PropertyMaster.SPMReference,
CONVERT(varchar, dbo.PropertyLease.StartDate,101) AS StartDate,
CONVERT(varchar, dbo.PropertyLease.DateSigned, 101) AS DateSigned
FROM dbo.PropertyLease
RIGHT OUTER JOIN dbo.PropertyMaster
ON dbo.PropertyLease.PropertyID = dbo.PropertyMaster.PropertyID
LEFT OUTER JOIN dbo.Tenants
ON dbo.PropertyMaster.PropertyID = dbo.Tenants.PropertyID
LEFT OUTER JOIN dbo.Lookup_PropertyManager
ON dbo.PropertyMaster.PropertyManagerID = dbo.Lookup_PropertyManager.PropertyManagerID
ORDER BY dbo.PropertyMaster.PropertyID
and here is my scalar-Valued Function
ALTER FUNCTION [dbo].[GetFullAddress]
-- Add the parameters for the function here
(#PropertyID as integer )
RETURNS varchar(250)
AS
BEGIN
DECLARE #AddressLine as varchar(40)
DECLARE #FullAddress as varchar(250)
SET #FullAddress = (SELECT LTRIM(ISNULL(TenantForeName + ' ', ' ') + TenantSurname) AS FullName FROM Tenants WHERE PropertyID = #PropertyID) + CHAR(10)
SET #AddressLine = (SELECT ISNULL(AddressLine1, '') FROM PropertyMaster WHERE PropertyID = #PropertyID)
SET #FullAddress = #FullAddress + #AddressLine + CHAR(10)
SET #AddressLine = (SELECT ISNULL(AddressLine2, '') FROM PropertyMaster WHERE PropertyID = #PropertyID)
IF #AddressLine <> ''
BEGIN
SET #FullAddress = #FullAddress + #AddressLine + CHAR(10)
END
SET #AddressLine = (SELECT ISNULL(AddressLine3, '') FROM PropertyMaster WHERE PropertyID = #PropertyID)
IF #AddressLine <> ''
BEGIN
SET #FullAddress = #FullAddress + #AddressLine + CHAR(10)
END
SET #AddressLine = (SELECT ISNULL(Town, '' ) FROM PropertyMaster WHERE PropertyID = #PropertyID)
IF #AddressLine <> ''
BEGIN
SET #FullAddress = #FullAddress + #AddressLine + CHAR(10)
END
SET #AddressLine = (SELECT ISNULL(PostCode, '') FROM PropertyMaster WHERE PropertyID = #PropertyID)
SET #FullAddress = #FullAddress + #AddressLine
RETURN #FullAddress
END
The problem is most likely this line
SET #FullAddress = (SELECT LTRIM(ISNULL(TenantForeName + ' ', ' ') + TenantSurname) AS FullName FROM Tenants WHERE PropertyID = #PropertyID) + CHAR(10)
You can change it to just get the first tenant by adding Top 1
SET #FullAddress = (SELECT TOP 1 LTRIM(ISNULL(TenantForeName + ' ', ' ') + TenantSurname) AS FullName FROM Tenants WHERE PropertyID = #PropertyID) + CHAR(10)
Or you can concatenate all of the tenants together.
SELECT #FullAddress = COALESCE(#FullAddress, '')
+ LTRIM(ISNULL(TenantForeName + ' ', ' ') + TenantSurname) AS FullName
FROM Tenants
WHERE PropertyID = #PropertyID) + CHAR(10)
P.S. If this is the issue. Your view is most like returning duplicate rows since you are left joining to the tenants table also. If you need a row for each tenant in your view, then you'll probably want to pass in the tenantid to the function and add that as a where clause to the query to get the tenant name.
This is not an answer to the question.
I'm posting it here only since it's almost impossible to read code posted in comments.
In addition to what user1221684 wrote in his/hers answer,
The rest of the function can be written like this:
SELECT #FullAddress = #FullAddress + CHAR(10) +
ISNULL(AddressLine1 + CHAR(10), '') +
ISNULL(AddressLine2 + CHAR(10), '') +
ISNULL(AddressLine3 + CHAR(10), '') +
ISNULL(Town + CHAR(10), '' ) +
ISNULL(PostCode, '')
FROM PropertyMaster WHERE PropertyID = #PropertyID
Explanation:
There really is no need to select a different column from the same table
in more then one query.
In sql server, when you concatenate a string (char(10) in this case) to a null value, the result is null. therefor ISNULL(AddressLine1 + CHAR(10), '') would return an empty string if AddressLine1 is null.

TSQL to transform Address into a Mailing Address - SQL Server 2005

I would like to transform an Address (Line1, Line2, Line3, City, State, ZIP) into a Mailing Address (Addr1, Addr2, Addr3, Addr4) that has no blank lines and the City, State and ZIP are concatenated together on one line. Having a function do this would be very nice.
i.e.
Line1=
Line2=123 Somewhere
Line3=
City=Detroit
State=MI
Zip=48000
Here is the table stucture for the incoming address:
IF OBJECT_ID('tempdb..#Employee') IS NOT NULL DROP TABLE #Employee
CREATE TABLE #Employee (Line1 VARCHAR(30), Line2 VARCHAR(30), Line3 VARCHAR(30),
City VARCHAR(17), State VARCHAR(2), ZIP VARCHAR(10))
GO
INSERT #Employee VALUES ('', '123 Somewhere', '', 'Detroit', 'MI', '48000')
SELECT * FROM #Employee
The resulting Mailing Address
Addr1=123 Somewhere
Addr2=Detroit MI 48000
Addr3=
Addr4=
or one field with cr character
Addr=
123 Somewhere cr
Detroit MI 48000 cr
cr
cr
A function would be nice to return Addr1, Addr2, Addr3 and Addr4 or just Addr with .
SqueezeAddress(Line1, Line2, Line3, City, State, ZIP)
Then SqueezeAddress would return Addr1, Addr2, Addr3, Addr4
or
Addr with cr
All the Addr1-4 lines would be VARCHAR (40) or if one field is used Addr VARCHAR (200)
Per Phil's request in the comments below, here is the current logic that is being used (Many fields were removed to make it easier to read):
SELECT Line1, Line2, Line3,
ISNULL(LTRIM(RTRIM(ADDR.City)) + ', ','') + ISNULL(ADDR.RegionCode,'')
+ ' ' + ISNULL(ADDR.PostalCode,'') AS Line4,
UPDATE #tmpBilling
SET Line1 = Line2, Line2 = NULL
WHERE ISNULL(Line1, '') = ''
AND ISNULL(Line2, '') <> ''
UPDATE #tmpBilling
SET Line2 = Line3, Line3 = NULL
WHERE ISNULL(Line2, '') = ''
AND ISNULL(Line3, '') <> ''
UPDATE #tmpBilling
SET Line2 = Line4, Line4 = NULL
WHERE ISNULL(Line2, '') = ''
AND ISNULL(Line4, '') <> ''
UPDATE #tmpBilling
SET Line3 = Line4, Line4 = NULL
WHERE ISNULL(Line3, '') = ''
AND ISNULL(Line2, '') <> ''
I may be missing something here, but if this is just simple string concatenation, then this would work...
Set up testing data (I added a few more samples)
IF OBJECT_ID('tempdb..#Employee') IS NOT NULL DROP TABLE #Employee
CREATE TABLE #Employee (Line1 VARCHAR(30), Line2 VARCHAR(30), Line3 VARCHAR(30),
City VARCHAR(17), State VARCHAR(2), ZIP VARCHAR(10))
GO
INSERT #Employee VALUES ('', '123 Somewhere', '', 'Detroit', 'MI', '48001')
INSERT #Employee VALUES ('123 Somewhere', 'Suite 500', '', 'Detroit', 'MI', '48002')
INSERT #Employee VALUES ('123 Somewhere', 'Suite 500', 'attn: JP', 'Detroit', 'MI', '48003')
SELECT * FROM #Employee
From here, all you have to do is stitch the strings together. This version presumes that you have both nulls and empty strings to factor out.
SELECT
isnull(nullif(Line1, '') + char(13) + char(10), '')
+ isnull(nullif(Line2, '') + char(13) + char(10), '')
+ isnull(nullif(Line3, '') + char(13) + char(10), '')
+ City + ' ' + State + ' ' + ZIP
+ char(13) + char(10) + '------------------------------'
from #Employee
Wrap that into a function:
CREATE FUNCTION dbo.SqueezeAddress
(
#Line1 varchar(30)
,#Line2 varchar(30)
,#Line3 varchar(30)
,#City varchar(17)
,#State varchar(2)
,#Zip varchar(10)
)
RETURNS varchar(200)
AS
BEGIN
RETURN isnull(nullif(#Line1, '') + char(13) + char(10), '')
+ isnull(nullif(#Line2, '') + char(13) + char(10), '')
+ isnull(nullif(#Line3, '') + char(13) + char(10), '')
+ #City + ' ' + #State + ' ' + #ZIP
+ char(13) + char(10) + '------------------------------'
END
GO
Lastly, put the function in the query:
SELECT dbo.SqueezeAddress(Line1, Line2, Line3, City, State, Zip)
from #Employee
More straightforward (and easier to debug, IMHO):
-------------------------------------------------------------
-- assumptions:
--
-- * nullable fields never contain an nil (empty) string.
-- every nullable column will contain either a proper value
-- or NULL.
--
-- * zipcode is a 5- or 9-digit USPS zip code, without a dash.
-- Addresses lacking a zipcode will be NULL.
--------------------------------------------------------------
drop table dbo.address
go
create table dbo.address
(
id int not null identity(1,1) primary key clustered ,
line1 varchar(100) null ,
line2 varchar(100) null ,
line3 varchar(100) null ,
city varchar(100) null ,
state varchar(2) null ,
zipcode varchar(9) null ,
)
go
-----------------------------------------------------------------------
-- create a work table and rotate the source table such that
-- the work table contains 1 row for each non-null row for each address
-----------------------------------------------------------------------
drop table #addr
go
create table #addr
(
id int not null , -- pk.1
line_no int not null , -- pk.2
value varchar(100) not null ,
primary key clustered ( id , line_no ) ,
)
go
insert #addr ( id , line_no , value )
select addr.id , addr.line_no , addr.value
from ( select id = t.id ,
line_no = row_number() over ( partition by t.id order by t.seq ) ,
value = t.value
from ( select id = id ,
seq = 1 ,
value = line1
from dbo.address where line1 is not null
UNION
select id = id ,
seq = 2 ,
value = line2
from dbo.address where line2 is not null
UNION
select id = id ,
seq = 3 ,
value = line3
from dbo.address where line3 is not null
UNION
select id = id ,
seq = 4 ,
value = ltrim(rtrim(
coalesce( city , '' )
+ case when city is not null and state is not null then ', ' else '' end
+ coalesce( state , '' )
+ case when ( city is not null or state is not null ) and zipcode is not null then ' ' else '' end
+ coalesce( left(zipcode,5) , '' )
+ case when len(zipcode) = 9 then '-' + right(zipcode,4) else '' end
))
from dbo.address
where city is not null
OR state is not null
OR zipcode is not null
) t
) addr
---------------------------------------------------------------------
-- finally, do another table rotation to build the desired result set
---------------------------------------------------------------------
select id = addr.id ,
line1 = line1.value ,
line2 = line2.value ,
line3 = line3.value ,
line4 = line4.value
from #addr addr
left join #addr line1 on line1.id = addr.id and line1.line_no = 1
left join #addr line2 on line2.id = addr.id and line2.line_no = 2
left join #addr line3 on line3.id = addr.id and line3.line_no = 3
left join #addr line4 on line4.id = addr.id and line4.line_no = 4
order by addr.id
Assuming that empty values are actually NULL and not empty strings and that City, State and Zip are requried:
;With AddressValues As
(
Select PK, Line1 As LineValue, 1 As LinePos
From AddressTable
Union All
Select PK, Line2, 2
From AddressTable
Union All
Select PK, Line3, 3
From AddressTable
Union All
Select PK, [City] + ', ' + [State] + ' ' + [Zip], 4
From AddressTable
)
, OrderedValues As
(
Select PK, LineValue
, Row_Number() Over( Partition By PK Order By LinePos ) As Num
From AddressValues
Where LineValue Is Not Null
)
, ValuesAsColumns As
(
Select PK
, Case When Num = 1 Then LineValue End As Line1
, Case When Num = 2 Then LineValue End As Line2
, Case When Num = 3 Then LineValue End As Line3
, Case When Num = 4 Then LineValue End As Line4
From OrderedValues
Group By PK
)
Update #tmpBilling
Set Line1 = VC.Line1
, Line2 = VC.Line2
, Line3 = VC.Line3
, Line4 = VC.Line4
From #tmpBilling As B
Join ValuesAsColumns As VC
On VC.PK = B.PK
EDIT
Here is the same result in the form of a function:
CREATE FUNCTION dbo.SqueezeAddress
(
#Line1 varchar(50)
, #Line2 varchar(50)
, #Line3 varchar(50)
, #City varchar(50)
, #State varchar(50)
, #Zip varchar(50)
, #LineNumToReturn int
)
RETURNS varchar(50)
AS
BEGIN
Declare #Result varchar(50);
With AddressValues As
(
Select #Line1 As LineValue, 1 As LinePos
Union All
Select #Line2, 2
Union All
Select #Line3, 3
Union All
Select #City + ', ' + #State + ' ' + #Zip, 4
)
, OrderedValues As
(
Select LineValue
, Row_Number() Over( Order By LinePos ) As Num
From AddressValues
Where LineValue Is Not Null
)
Select #Result = LineValue
From OrderedValues
Where Num = #LineNumToReturn
Return #Result
END
GO
Select dbo.SqueezeAddress(null, '123 Main St', null, 'Detroit', 'MI', '12345', 1)
, dbo.SqueezeAddress(null, '123 Main St', null, 'Detroit', 'MI', '12345', 2)
, dbo.SqueezeAddress(null, '123 Main St', null, 'Detroit', 'MI', '12345', 3)
, dbo.SqueezeAddress(null, '123 Main St', null, 'Detroit', 'MI', '12345', 4)
)

Resources