I'm trying to get a string with date range of dates, such as "W202243 from 24-Oct a 30-Oct", going from each monday to sunday. To achieve this i'm using impala, creating the string step by step.
My function is:
select distinct concat('W',substr(cast(a.day_key AS string),1,4), IF (DAYOFWEEK(from_unixtime(unix_timestamp(cast(cast(a.day_key AS string) AS string), "yyyyMMdd")))=2, cast(weekofyear(from_unixtime(unix_timestamp(cast(cast(a.day_key AS string) AS string), "yyyyMMdd")))-1 AS string), cast(weekofyear(from_unixtime(unix_timestamp(cast(cast(a.day_key AS string) AS string), "yyyyMMdd"))) AS string)), ' from ', SUBSTR(substr(cast(TRUNC(date_add(from_unixtime(unix_timestamp(cast(a.day_key AS string), "yyyyMMdd")),-1),'DY') AS string), 9,10),1,2), '-', SUBSTR(MONTHNAME(date_add(TRUNC(date_add(from_unixtime(unix_timestamp(cast(a.day_key AS string), "yyyyMMdd")),-1),'DY'),1)),1,3),' a ', SUBSTR(substr(cast(date_add(TRUNC(date_add(from_unixtime(unix_timestamp(cast(a.day_key AS string), "yyyyMMdd")),-1),'DY'),6) AS string), 9,10),1,2), '-', SUBSTR(MONTHNAME(date_add(TRUNC(date_add(from_unixtime(unix_timestamp(cast(a.day_key AS string), "yyyyMMdd")),-1),'DY'),6)),1,3))
The result is almost correct, except when the first day of week is also the last of month, giving me this unwanted result: (Ex. W202244 FROM 31-Nov a 06-Nov -> November instead of October).
Any ideias of what can i add to the query to solve this?
While this reads like plain English it seems that specific phrases are being used as "delimiters". You can use the CHARINDEX function to break this statement down into 3 columns, then from there cast/convert each column into it's final form. You could probably do this all in 1 step but it would be a mess to write and to read and I'm not sure if it would offer any performance benefit
You could also use REPLACE to turn this column into a delimited string, then parse that. For example:
declare #string nvarchar(max) = 'W202243 from 24-Oct a 30-Oct'
select REPLACE(REPLACE(#string, ' from ', ','),' a ', ',')
This returns:
W202243,24-Oct,30-Oct
Which is comma delimited. You can change the delimiter to whatever. But from there it would be easy to get 3 distinct columns and convert them accordingly.
Related
How can I find strings in a column that are doubled-up and correct them? I feel like there is an easy answer to this I just can't think of it.
Example:
I want to find instances of a repeating string, example "SolonSolon", and then update the column to "Solon".
Update:
They're always the same. No extra characters, but might have a space as part of the repeating value. Other examples would be...
"PlacePlace", "TreeTree", "OrangeOrange", "TravisMemorialHSTravisMemorialHS", "Texas HSTexas HS"
You can check if the string is equal to the first half replicated.
SELECT LEFT(YourCol,LEN(REPLACE(YourCol, ' ', 'x'))/2)
FROM YourTable
WHERE YourCol = REPLICATE(LEFT(YourCol,LEN(REPLACE(YourCol, ' ', 'x'))/2),2)
The reason for the REPLACE of spaces with x before calculating the LEN is because trailing spaces are ignored by this function. You can also use the technique in #lptr's answer for this but an edge case will be if the string was varchar(8000) and already 8000 characters long in which case concatenating an extra character won't do anything (LEN(SPACE(8000) + 'x') is 0).
..replace the first half of the value with an empty string..if there is nothing left..the value consists of two equal parts
select *, substring(c, 1, (len(c+'.')-1)/2)
from
(
values
('solosolo'), ('yoyo'), ('andand'), ('1212'),(' . .'),
('ababc'), ('onetwoone')
) as t(c)
where replace(c, substring(c, 1, (len(c+'.')-1)/2), '') = '';
Another alternative. The query removes inner spaces using REPLACE(str_col, ' ', ''), removes leading/traling spaces using TRIM, and checks to make sure the first half of the string equals the second half.
select left(no_spaces.str_col, v.str_len/2)
from foo f
cross apply (values (replaced trim(f.str_col), ' ', '')) no_spaces(str_col)
cross apply (values (len(no_spaces.str_col))) v(str_len)
where no_spaces.str_col=replicate(left(f.str_col, v.str_len/2), 2);
I'm trying to isolate a certain character string from a text cell.
For example, I would like to extract "AB-T120-15" from the string "His server ID was AB-T120-15 and his problem was that he needed a reboot"
AB-T120-15 is an example, but they would all be codes of a max length of 13 characters starting by something like AB-T, CL-R, etc.
The codes can appear anywhere in a text field of the column.
string_split() cannot be used since the DB we are under is older.
I have tried many combinations of Substring and LEFT, but I cannot seem to have it worked.
Any thoughts?
String operations are not the strength of SQL Server -- which I assume you are using.
You can do this with rather painful string manipulation:
select left(stuff(str, 1, patindex('%[A-Z][A-Z]-[A-Z]%', str) - 1, ''),
charindex(' ', stuff(str, 1, patindex('%[A-Z][A-Z]-[A-Z]%', str), '') + ' ')
)
from (values ('His server ID was AB-T120-15 and his problem was that he needed a reboot')) v(str);
I uploaded some data from excel sheet to a table in sql , I would like to use part of the string that I inserted into the column PPRName and insert into another table [Verify].
The data in the column when inserted looks like this:
August 2018 [ NW: Construction MTP021 - Building and Civil Construction: Masonry NQF 3 ]
I want to insert this part of the string :
NW: Construction MTP021 - Building and Civil Construction: Masonry NQF 3
into another table [Verify] for every PPR Name in the PPRName column. The names of the PPRs vary in length but all come in same format.
I would also like to extract the August 2018 and cast it as a date and insert into my table [Verify].
I am not sure how to use Charindex and Substrings to achieve this.
i tried this but no data was returned
select SUBSTRING([PPR_Caption],charindex('[',[PPR_Caption]),charindex([PPR_Caption],']'))
FROM [dbo].[PPRS]
You incorrectly use the 2nd CHARINDEX and you incorrectly use the SUBSTRING commands.
SELECT SUBSTRING(PPR_Caption, CHARINDEX("[", PPR_Caption) + 1, CHARINDEX("]", PPR_Caption) - CHARINDEX("[", PPR_Caption) - 1)
FROM PPRS
SUBSTRING uses a start and a lenght, not the start and end point. To get the length use your end point and substract the start point (and correct the 1 position offset with -1).
In your 2nd CHARINDEX you switched the string to search in and the string to look for.
String operations like this are cumbersome in SQL Server.
Try this:
select replace(v2.str_rest, ' ]', '') as name, cast(str_start as date) as dte
from (values ('August 2018 [ NW: Construction MTP021 - Building and Civil Construction: Masonry NQF 3 ]')
) v(str) cross apply
(values (stuff(v.str, 1, charindex('[', str) + 1, ''), substring(v.str, 1, charindex('[', str) -1))
) v2(str_rest, str_start);
SQL Server is pretty good about guessing formats for converting dates, so it will actually convert the date without the day of the month.
I would like to substring from list of table type.
Code is below
#Description AS dbo.ListStringTableType
And #Description have like list of data below
Test+Again
Today+Tomorrow
And looking to sub string by char '+'
Col1 Col2
----- -----
Test Again
Today Tomorrow
SQL Server 2016 has the split() function. But, you can instead just do:
select v.col1, v.col2
from t outer apply
(values (left(col, charindex('+', col) - 1),
stuff(col, 1, charindex('+', col), '')
)
) v(col1, col2);
You can get the substring using charindex as below.
declare #var varchar(20)='Test+Again'
select substring(#var,1,CHARINDEX('+',#var)-1) as col1
,substring(#var,CHARINDEX('+',#var)+1,len(#var)) as col2
The #var variable should be the column in your case.
Select left(description,charindex('+', description)-1) as col1,
right(description,len(description)-charindex('+', description)) as col2
CharIndex will help to find the 1st position of the string we provide, For col1 we require string before string '+', so we are using the 'left' function here.
'left' will fetch the number of letters from the start to the length mentioned(extracted via charindex function, will return the position of the exact string in the given input).
Similarly, for col2 we require string after string '+', so we are using the 'right' function here.
'right' will fetch the number of letters from the last to the length mentioned(total length of the string - length extracted via charindex function).
For More Info about, Right, Left Function, please use below link.
https://social.technet.microsoft.com/wiki/contents/articles/17948.t-sql-right-left-substring-and-charindex-functions.aspx
I would like to get all the characters in a field before a space
For example, if field1 is "chara ters"
I want it to return "chara"
What would this select statement look like?
SELECT LEFT(field1,LOCATE(' ',field1) - 1)
Note that if the string in question contains no spaces, this will return an empty string.
Below is another method that works and may seem a bit simpler to some. It uses the SUBSTRING_INDEX MySQL function. A 1 returns everything before the first space, and a -1 returns everything after the last space.
This returns 'chara':
SELECT SUBSTRING_INDEX( field1, ' ', 1 )
This returns 'ters':
SELECT SUBSTRING_INDEX( field1, ' ', -1 )
Details
A positive value will look for your specified character from the start of the string, and a negative value will start from the end of the string. The value of the number indicates the quantity of your specified character to look for before returning the remaining piece of the string. If the character you are searching for does not exist, the entire field value will be returned.
In this case, a -2 would return everything to the right of the second to last space, which doesn't exist in this example, so the entire field value will be returned.
You would need some string operations for that. Assuming every field has at least one space character:
SELECT SUBSTR(field1, 0, LOCATE(' ', field1)) FROM your_table;
Safe approach:
SELECT IF(
LOCATE(' ', field1),
SUBSTR(field1, 0, LOCATE(' ', field1)),
field1
) FROM your_table;
For a generalized approach that returns the nth value (one-based index) from a column containing delimited values:
select SUBSTRING_INDEX(SUBSTRING_INDEX(my_column,#delimiter,#index),#delimiter,-1) from my_table;
This will return the entire column contents if the delimiter does not exist, and the last field if the index value exceeds the number of fields.
For instance, if my_column contains 'foo bar baz' and you want the 2nd field:
select SUBSTRING_INDEX(SUBSTRING_INDEX(my_column,' ',2),' ',-1) from my_table;
will return bar, and if you specify the 4th field (which does not exist):
select SUBSTRING_INDEX(SUBSTRING_INDEX(my_column,' ',4),' ',-1) from my_table;
will return baz (the last field).