I am trying to extract the City from an address where everything is in one column, between last and second to last comma - sql-server-2008-r2

I am trying to extract the city from an address where everything is in one column, between last and second to last comma.
For example Address column contains
LYNDEN COURT,CHARTWELL,HAMILTON,3210
CNR DIXON & BANNISTER STREETS,MASTERTON,MASTERTON,5810
3C,SHORT STREET,NEWMARKET,AUCKLAND,1023
As you can see, there is not always the same number of comma's. But I need to extract "Hamilton", "Masterton", and "Auckland" in these examples.
Want it as part of a select statement along with other fields in the same table.
Using SQL Server 2008 R2, but also using SSMS 2014 to access the server

I probably over complicated this but you can try
DECLARE #var VARCHAR(50) = 'CNR DIXON & BANNISTER STREETS,MASTERTON,MASTERTON,5810'
SELECT REVERSE(SUBSTRING(REVERSE(#var), CHARINDEX(',',REVERSE(#var)) +1, CHARINDEX(',', REVERSE(#var), CHARINDEX(',',REVERSE(#var)) + 1) - CHARINDEX(',',REVERSE(#var)) -1))

Related

SSRS -How to get month name from integer value when connecting to IBM-DB2(AS400)

I am using SSRS to create a dataset from a query having a column in AS400 with month number which i get based on a condition .i am able to get the month number . But when i try to get month name SSRS does not accept the query .However if i run the same query on AS400 the query successfully runs
To test my query i ran it in AS400 using MONTHNAME(MONTH) it runs successfully however SSRS does not accept the same query as correct.Below is my query.
SELECT DISTINCT SLMONTH, MONTHNAME(SLMONTH) AS Expr1
FROM VEHICLE.VHTSALSUM
WHERE (SLMGCD = ?) AND (SLMODLCD = ?) AND (SLMODLYR = ?) AND (SLYEAR = ?)
Instead of doing this in on the server, you could just return the month number to SSRS and use an expression to convert it to the month name there.
The expression would simply be
=MonthName(Fields!SLMONTH.Value)
This assumes AS/400 returns month numbers 1 - 12
Personally I think this is a better approach anyway as it means you have the month number to sort by. It is usually better to do your presentation in the report itself.
Edit based on feedback:
To do this for use in a parameter..
Create a dataset that returns just your month numbers.
Right-Click the dataset name and go to properties
On the Fields Tab, add a new field called MonthName for example
Click the function button for the field source type the expression =MONTHNAME(Fields!MonthID.Value)
The month name will then be available directly in your dataset for use in your parameter

Consecutive numbers - SQL Server 2008 R2

I need to put numbers in sequential order (1, 2, 3, 4...) in a table column.
These are invoice numbers, they need to be consecutives, no gaps, no repeated. Is a mandatory requirement, in fact is a fiscal requirement, so I can't skip it.
My current aproach is to use a second "Numbers" table with 2 columns (Id, LastNumber) with one record on it, Id = 1.
This is what I'm doing now:
1. SELECT (LastNumber + 1) as Number from Numbers with (xlock, rowlock) where Id = 1
2. assign the number, do other inserts and updates to other tables.
3. UPDATE Numbers set LastNumber = #Number where Id = 1 --#Number is the number retrieved in step 1
4. End of Transaction
I'm trying to use locking, and don't know if I am correct, what is the most efficient solution to do this?
As I stated above, is a mandatory requeriment, the number must be consecutives, no gaps, no repeated.
The table is used in an app from several clients in a network. I use Sql Server 2008 R2.
I have found this similar question:
Sequential Invoice Numbers SQL server
the solution given there is with some T-SQL code that get the max number in the table, but what happens if 2 clients called this code at the same time? 2 repetead numbers will be generated?
Thanks
You'll want a transaction. By doing the update first, you're effectively locking the row from other shared locks until your transaction is completed, then returning the new number.
BEGIN TRAN
UPDATE Numbers SET Number = Number + 1 WHERE Id = 12
SELECT Number FROM Numbers WHERE Id = 12
COMMIT

Trying to find the last character in a non-standard length string

I'm a relatively new coder and I've been struggling with the following problem for a few days. I am trying to separate the characters after the last period in an email address so I can group results by them. To do this for the text after the # symbol, I wrote the following code:
select lower(substring(email, position('#' in email))) as email
This code returns things like #gmail.com or #yahoo.com, which I can then group by in my longer query. However, I would also like to compare the .com results to the .net results. When I type a similar query:
select lower(substring(email, position('.' in email))) as email
it returns the first period in the email address. So my email would be returned as .lastname#gmail.com rather than .com. I've experimented with right( and left(, but these don't work with substring in Postgresql. Does anyone have any other suggestions? Thanks!
Try this. The trick was using reverse to find where that last period was.
SQL Fiddle Example
select
substring(email, char_length(email) - position('.' in (reverse(email))) + 1) as Domain
from yourTable
Try something like:
select regexp_matches(email, '[^.]+$', 'g')
from your_table

SSRS and string parsing to produce a report

A friend told me that his new employer needs an SSRS report that parse a column that contains n consecutive occurrences of
1) the literal "Date:"
2) An optional separator character
3) followed by a date in DD-MM-YY format (leading zeros are optional)
4) a separator space
5) A single "WORD" of data that is associated with the date. This word will have no embedded spaces.
I'll populate a Sample table with data that meets this critera to give you an example to make it clear:
CREATE TABLE [dbo].[Sample](
[RowNumber] [int] NOT NULL,
[DataMess] [varchar](max) NOT NULL
) ON [PRIMARY]
INSERT [dbo].[Sample] ([RowNumber], [DataMess]) VALUES (1, N'Date:12-21-13 12/13/14/15 Date:4-2-11 39/12/134/14 Date:4-1-13 19/45/5/12')
INSERT [dbo].[Sample] ([RowNumber], [DataMess]) VALUES (2, N'Date:7-21-13 12/13/14/15 Date:8-21-12 39/12/34/14 Date:12-1-13 19/4/65/12')
INSERT [dbo].[Sample] ([RowNumber], [DataMess]) VALUES (3, N'Date:3-21-13 12/11233/14/15 Date:4-28-13 39/12/34/14 Date:9-19-13 19/45/65/12')
For the first record, "12/13/14/15" is considered to be the "Word" of data that is associated with the Date 12-21-13.
He was aked to produce the following report in SSRS:
Row Number DataMess
1 Date: 12-21-13 12/13/14/15
Date: 4-1-13 19/45/5/12
Date: 4-2-11 39/12/134/14
2 Date:12-1-13 19/4/65/12
Date:7-21-13 12/13/14/15
Date:8-21-12 39/12/34/14
3 Date:9-19-13 19/45/65/12
Date:4-28-13 39/12/34/14
Date:3-21-13 12/11233/14/15
Note that the Dates for each source row number are sorted in descending arder alomng with the associated wor of data.
I don't know SSRS, but my reaction was to recommend to him that he not even attempt the task but to tell his employer that the data shouldn't really be trying to do all of that ugly string parsing with T-SQL. Instead this repeating "Date: DATA" should be stored in individual child records that are associated with a parent Row record. I believe that the code would be ugly, inefficient, brittle and hard to maintain. What are your thoughts?
Assuming that management\client is always right or to conceed that "ideally" this is correct, but "for now" we need a SQL that produces the following report, how would one do this? The expectation was that this can be produced quickly ( a half day, for example)
You are of course correct, it's certainly far from the best way of storing the data. Any way of extracting the data for this report will be much more complex than it would be if it was stored differently.
However, based on the data it still wouldn't be too tough to actually generate the report. Due to the table structure actually generating the dataset for the report would be the hardest part.
So to generate the dataset, you need to split the data in DataMess to get one row per Date/Word, and be able to extract the date from that split data to be able to order by date as required.
Take your pick on how you want to split the data:
Split function equivalent in T-SQL? has many options, as does this link - Best Split Function.
Here's a SQL Fiddle with one of the functions in action.
Once you've split the data, use the appropriate function to extract the date portion, i.e. between the colon and the space before the word data, then CAST this as a date.
Once you've actually got the dataset, it's the most trivial of reports - just add a row group based on RowNumber, add the split Date/Word data as a detail field and you're done. Make sure the dataset is ordered by the extracted date field, even though you don't actually display this in the report.
As an interim measure I would certainly expect this to be doable in half a day of work or so. So for just this report it's not too bad, but for anything else you'll probably have trouble.
For a few rows it will likely run fine, but on any non-trivial sized dataset performance will be suboptimal.
Thank you. Here's what I did for the remaining part to get the dates sorted in DESC order.
SELECT
RowNumber
,'Date: ' + ss.Item AS Data
--,cast(substring(ss.Item, 1, charindex(' ' , ss.Item) ) AS date)
FROM
Sample s
CROSS apply dbo.SplitStrings_XML(s.DataMess,
N'Date:') ss
WHERE
Item IS NOT NULL
ORDER BY
rownumber,
cast(substring(ss.Item, 1, charindex(' ' , ss.Item) ) AS date) desc
If the data fails to hold up to this expected format and we encounter a date that is not valid, then the whole report blows up.

SQL Server 2008: Pivot column with no aggregate function workaround

Yes I know, this question has been asked MANY times but after reading all the posts I found that there wasn't an answer that fits my need. So, Heres my question. I would like to take a column of values and pivot them into rows of 6 columns.
I want to take this...... And turn it into this.......................
G Letter Date Code Ammount Name Account
081278 G 081278 12 00123535 John Doe 123456
12
00123535
John Doe
123456
I have 110000 values in this one column in one table called TempTable. I need all the values displayed because each row is an entity to itself. For instance, There is one unique entry for all of the Letter, Date, Code, Ammount, Name, and Account columns. I understand that the aggregate function is required but is there a workaround that will allow me to get this desired result?
Just use a MAX aggregate
If one row = one column (per group of 6 rows) then MAX of a single value = that row value.
However, the data you've posted in insufficient. I don't see anything to:
associate the 6 rows per group
distinguish whether a row is "Letter" or "Name"
There is no implicit row order or number to rely upon to generate the groups
Unfortunately, the max columns in a SQL 2008 select statement is 4,096 as per MSDN Max Capacity.
Instead of using a pivot, you might consider dynamic SQL to get what you want to do.
Declare #SQLColumns nvarchar(max),#SQL nvarchar(max)
select #SQLColumns=(select '''+ColName+'''',' from TableName for XML Path(''))
set #SQLColumns=left(#SQLColumns,len(#SQLColumns)-1)
set #SQL='Select '+#SQLColumns
exec sp_ExecuteSQL #SQL,N''