Remove Leading Commas via Coalasce and NULLIF? - sql-server

UPDATE PropertyInformationDump
SET RegistryAdd = COALESCE(NULLIF(b.OCAREOF, ''), b.OCAREOF + ', ','') +
COALESCE(NULLIF(b.O1STADD, ''), b.O1STADD + ', ','') +
COALESCE(NULLIF(b.O2NDADD, '') + b.O2NDADD + ', ','') +
COALESCE(b.OSTNAME + ', ','') + COALESCE(b.OCITYST + ' ','') +
COALESCE(NULLIF(b.OZIP, ''), b.OZIP,'')
FROM dbo.vw_BRT b
WHERE BRTNumber = b.PARCEL
GO
Looking to remove the commas that are in the front of these combined strings. Here is an example of what is happening:
, , 1350 SUSQUEHANNA AVE, PHILADELPHIA PA 19125
MICHAEL J CARLONE, 10050 ROOSEVELT BLVD, PHILADELPHIA PA 191163924
Need it to always look like:
1350 SUSQUEHANNA AVE, PHILADELPHIA PA 19125
or just how the one with the OCAREOF filled:
MICHAEL J CARLONE, 10050 ROOSEVELT BLVD, PHILADELPHIA PA 191163924
I need to get rid of those commas if the field is empty or null. Apparently I am doing this incorrectly!

using SQL Server 2005 the following should work
UPDATE PropertyInformationDump
SET RegistryAdd =
CASE WHEN Len(b.OCAREOF) > 0 THEN b.OCAREOF + ',' ELSE '' END +
CASE WHEN Len(b.O1STADD) > 0 THEN b.O1STADD + ',' ELSE '' END +
CASE WHEN Len(b.O2NDADD) > 0 THEN b.O2NDADD + ',' ELSE '' END +
CASE WHEN Len(b.OSTNAME ) > 0 THEN b.OSTNAME + ',' ELSE '' END +
CASE WHEN Len(b.OCITYST) > 0 THEN b.OCITYST+ ',' ELSE '' END +
CASE WHEN Len(b.OZIP) > 0 THEN b.OZIP+ ',' ELSE '' END
FROM dbo.vw_BRT b
WHERE BRTNumber = b.PARCEL
If the fields are either empty of have data then you can ignore using isNull()

Use this:
COALESCE(NULLIF(b.OCAREOF + ', ', ''),'')
UPDATE
If your fields are not nullable use this:
CASE WHEN LEN(b.OCAREOF) = 0 THEN '' ELSE b.OCAREOF + ', ' END +
....

Related

Need help adding WHERE clause in pre-written SQL statement

Preface: my SQL is rudimentary. I received a SQL query from a vendor, it selects and exports every single employee comment and other data from a few different DBs as CSV meant for import, it was written by them but they're not helping with this request. The query is pulling so much data it makes a large time consuming file for import. So I want to add to / modify the query to have a "WHERE date > whateverdate" to narrow my results to recent data. For example, I want to pull only comments entered in the past 2 days.
The column I'm looking to add the clause for is the column "A.CMS502", defined as datetime. I believe this is the only relevant column in this query. An example date in this column is "2003-10-06 17:05:21.000". I am using SQL Server 2008 if it helps. Is it possible here? Thank you.
SELECT
'ID,Acct/LnNbr,NoteCreatedDate,CollectorId,ApplytoAll,Note'
UNION ALL
SELECT
ID + ',' + ID + ',' + NoteCreatedDate + ',' + CollectorId + ',' + 'No' + ',' + Note
FROM
(SELECT
CASE WHEN SUBSTRING(A.CMS301,LEN(A.CMS301),1) = 'S'
THEN SUBSTRING(A.CMS301,1,LEN(A.CMS301) - 1)
ELSE A.CMS301
END + '-' +
CASE WHEN SUBSTRING(A.CMS301,LEN(A.CMS301),1) = 'S'
THEN 'S' ELSE 'L'
END AS [ID],
REPLACE(CONVERT(VARCHAR, A.CMS501, 10), '-', '') AS [NoteCreatedDate],
CASE WHEN U.CMS1201 IS NOT NULL
THEN U.CMS1205 + ' ' + U.CMS1204
ELSE (SELECT CMS1205 + ' ' + CMS1204 FROM sysUSER WHERE CMS1201 = 'PSUSER')
END AS CollectorId,
CAST(A.CMS512 AS NVARCHAR(MAX)) AS [Note]
FROM
ACTIVITY AS A
LEFT JOIN
sysUSER AS U ON A.CMS503 = U.CMS1201
WHERE
A.CMS504 NOT IN (411,500,511,711,804,900,901,903,907,2000,999777)
AND A.CMS504 NOT BETWEEN 1102 AND 1199) AS S
Try this, this will output last 2 days.
SELECT 'ID,Acct/LnNbr,NoteCreatedDate,CollectorId,ApplytoAll,Note'
UNION ALL
SELECT ID + ',' + ID + ',' + NoteCreatedDate + ',' + CollectorId + ',' + 'No' + ',' + Note
FROM
(
SELECT CASE WHEN SUBSTRING(A.CMS301,LEN(A.CMS301),1) = 'S' THEN SUBSTRING(A.CMS301,1,LEN(A.CMS301) - 1) ELSE A.CMS301 END
+ '-' + CASE WHEN SUBSTRING(A.CMS301,LEN(A.CMS301),1) = 'S' THEN 'S' ELSE 'L'
END AS [ID]
,REPLACE(CONVERT(varchar,A.CMS501,10),'-','') AS [NoteCreatedDate]
,CASE WHEN U.CMS1201 IS NOT NULL THEN U.CMS1205 + ' ' + U.CMS1204 ELSE
(SELECT CMS1205 + ' ' + CMS1204 FROM sysUSER WHERE CMS1201 = 'PSUSER')
END AS CollectorId
,CAST(A.CMS512 AS nvarchar(max)) AS [Note]
FROM ACTIVITY AS A
LEFT JOIN sysUSER AS U
ON A.CMS503 = U.CMS1201
WHERE A.CMS504 NOT IN (411,500,511,711,804,900,901,903,907,2000,999777)
AND A.CMS504 NOT BETWEEN 1102 AND 1199
AND A.CMS502 >= DATEADD(D, -2, GETDATE())
) AS S

Order by Empty String Last on Concatenated Column

I am trying to order a table alphabetically, ascending, with nulls last but am having problems.
The code below produces the following error:
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
select distinct
'item' = othertab..item,
'stockedFor' = tab..stocked_for
+ ', ' + tab..stockedFor2
+ ', '+ tab..stockedFor3
from tab
order by case when stockedFor is null then 1 else 0 end, stockedFor
How can I return stockedFor alphabetically and nulls last?
Just wrap it in another select statement:
select stockedFor
from (
select distinct
'stockedFor' = tab..stocked_for
+ ', ' + tab..stockedFor2
+ ', '+ tab..stockedFor3
from tab
) x
order by case when stockedFor is null then 1 else 0 end, stockedFor
Since you are removing duplicates, a workaround is to use GROUP BY to remove duplicates instead of DISTINCT. The question has changed but the method still applies if putting all columns in the SELECT in the GROUP BY.
For example:
select
'item' = othertab..item,
'stockedFor' = tab..stocked_for
+ ', ' + tab..stockedFor2
+ ', '+ tab..stockedFor3
from tab
GROUP BY othertab..item,
tab..stocked_for
+ ', ' + tab..stockedFor2
+ ', '+ tab..stockedFor3
order by case when stockedFor is null then 1 else 0 end, stockedFor

Retun x character AFTER a string SQL Server

I'm trying to return the following 4 characters after a string in a column 'E.Notes'
Example string 'Code: ABCD'
Target output 'ABCD'
I've tried to no avail ;-(
CASE WHEN CHARINDEX('<strong>Code:</strong> ', E.Notes) > 0 THEN
LEFT(E.Notes, CHARINDEX('<strong>Code:</strong> ', E.Notes) 4)
ELSE '' END
USE SUBSTRING() OR RIGHT() SHOULD BE OK.
CASE WHEN CHARINDEX('<strong>Code:</strong> ', E.Notes) > 0 THEN
SUBSTRING(E.Notes, CHARINDEX('<strong>Code:</strong> ', E.Notes) + LEN('<strong>Code:</strong> '), 255)
ELSE '' END
CASE WHEN CHARINDEX('<strong>Code:</strong> ', E.Notes) > 0 THEN
RIGHT(E.Notes,LEN( E.Notes) + 1 - LEN('<strong>Code:</strong>') - CHARINDEX('<strong>Code:</strong> ', E.Notes) )
ELSE '' END
AND YOU CAN USE RTRIM() OR LTRIM() TO GET RID OF SPACES.
Try this
DECLARE #Notes VARCHAR(200) = '<strong>Code:</strong> ABCDkkkk'
SELECT CASE
WHEN CHARINDEX('Code:', #Notes) > 0
THEN RIGHT(#Notes, LEN(#Notes) - CHARINDEX('Code:', #Notes) - 14)
ELSE ''
END
EDITED
By OP's demand to get only first 4 character from the string.
SELECT CASE
WHEN CHARINDEX('Code:', #Notes) > 0
THEN LEFT(RIGHT(#Notes, LEN(#Notes) - CHARINDEX('Code:', #Notes) - 14), 4)
ELSE ''
END

SQL Case Issue Setting Variable

Why is it that I can't do the below script and how would I go about fixing it? I get the error Inccorect syntax near '='. I was doing it using ...= 1 THEN 'D' ELSE '' END as Aset but I need to check Aset and Bset in the third Case so I declared Aset and Bset instead.
declare #Aset varchar(10)
declare #Bset varchar(10)
UPDATE m
SET m.new_name = m.new_name + ' ' + #ASet + AndSet + #BSet + ' Type'
FROM contactMaster m
inner join contact c on
m.contactid = c.contactid
CROSS APPLY (
SELECT CASE #Aset WHEN (c.category1|
c.category2|
c.category3|
c.category4) = 1 THEN 'C' ELSE '' End
,CASE #Bset WHEN (c.category5|
c.category6|
c.category7|
c.category8) = 1 THEN 'D' ELSE '' END
,CASE WHEN #BSet = 'D' and #ASet = 'C' THEN ' & ' ELSE '' END AS AndSet
) AS CA1
I don't have your table schema or data, so I had to wing it and couldn't test it, but see if this might work:
UPDATE m
SET m.new_name = m.new_name
+ ' '
+ CA1.ASet
+ CASE WHEN
(
CA1.Aset = 'C' AND
CA1.Bset = 'D'
)
THEN ' & ' ELSE '' END
+ CA1.BSet + ' Type'
FROM contactMaster m
JOIN contact c on m.contactid = c.contactid
CROSS APPLY (
SELECT CASE WHEN
(
c.category1 |
c.category2 |
c.category3 |
c.category4
)
= 1 THEN 'C' ELSE '' END AS Aset,
CASE WHEN
(
c.category5 |
c.category6 |
c.category7 |
c.category8
)
= 1 THEN 'D' ELSE '' END AS Bset
) AS CA1

Cannot set the Order By to my SQL Statement, need a workaround

I understand that I cannot have the SQL order by PaymentDate but my results come out not in Payment Date Order. Is there an easy way I can make sure the PERIOD column is in actual date order?
The SQL below works perfect its just if i add "--order by f.PaymentDate" I get 'Column "PaymentItem.PaymentDate" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.' So i'm trying to think how to get around this
select g.SiteDescription,
case a.Surname when '' then a.Company else a.Surname + ', ' + isnull(a.Forename,'') end as Landowner,
h.PaymentTypeDesc as [RentalElection],
d.RelevantProportion,#IN_showRelevantProportion as ShowRelevantProportion,
g.SiteId,a.LandownerId,e.PaymentTypeId,e.PaymentCategoryId,
case #IN_OutputFormat
when 'Monthly' then
convert(char(3), f.PaymentDate, 0) + '-' + ltrim(Year(f.PaymentDate))
when 'Annually' then
ltrim(Year(f.PaymentDate))
else
ltrim(Year(f.PaymentDate)) + ' Qtr ' + ltrim(datepart(quarter,f.PaymentDate))
end as Period,
sum(isnull(f.ActualPayment,0)) as Total
from
[Site] g,
Landowner a,
[Site] c,
SiteAgreement d,
Payment e,
PaymentItem f,
PaymentType h
where a.LandownerId = d.LandownerId
and g.SiteId = d.SiteId
and e.SiteAgreementId = d.SiteAgreementId
and f.PaymentId = e.PaymentId
and e.PaymentTypeId = h.PaymentTypeId
and f.paymentdate between #IN_daysFrom and #IN_daysTo
and isnull(f.ActualPayment,0) != 0
group by g.SiteDescription,
case a.Surname when '' then a.Company else a.Surname + ', ' + isnull(a.Forename,'') end,
h.PaymentTypeDesc,
d.RelevantProportion,
g.SiteId,a.LandownerId,e.PaymentTypeId,e.PaymentCategoryId,
case #IN_OutputFormat
when 'Monthly' then
convert(char(3), f.PaymentDate, 0) + '-' + ltrim(Year(f.PaymentDate))
when 'Annually' then
ltrim(Year(f.PaymentDate))
else
ltrim(Year(f.PaymentDate)) + ' Qtr ' + ltrim(datepart(quarter,f.PaymentDate))
end
--order by f.PaymentDate
Order by the entire expression that uses your Payment Date column:
ORDER BY case #IN_OutputFormat
when 'Monthly' then
convert(char(3), f.PaymentDate, 0) + '-' + ltrim(Year(f.PaymentDate))
when 'Annually' then
ltrim(Year(f.PaymentDate))
else
ltrim(Year(f.PaymentDate)) + ' Qtr ' + ltrim(datepart(quarter,f.PaymentDate))
end
I got this going by just ordering at a string in format YYYY-MM. The MM needed left padded 0 of course:
CONVERT(CHAR(4), f.PaymentDate, 120) + ' ' + right('0'+ rtrim(ltrim(datepart(mm,f.PaymentDate))), 2)

Resources