Substring of a Substring - sql

I have a text field (field named "BiographyText" in the "Employs" table) in SQL Server 2008 which stores KPI target figures:
rebfirst60,
reifirst1.3,
retfirst50
The first target is 60, for RebFirst, the second is 1.3 for ReiFirst and 50 for the third, RetFirst.
I want to be able to return the 3 different numerical values, as these would be deemed the targets for each kpi for a certain employee.
I am having a complete mind block trying to figure out the best way to do this, any advice/help?
Overall I am trying to find the kpiname ("rebfirst") and then retrieve the next 2 characters/digits
I tried the following, but it errors on function 2 of the first substring, as it is non-numeric:
select SUBSTRING(biographytext,SUBSTRING('rebfirst',1,2),2) from employs
Thanks

Try this
SELECT
CASE WHEN PatIndex('%[a-z]%',REVERSE(BiographyText)) > 0
THEN RIGHT(BiographyText,PatIndex('%[a-z]%',REVERSE(BiographyText))-1)
ELSE '' END AS target
FROM employs
and also check another solution using function

From Post The first target is 60, for RebFirst, the second is 1.3 for ReiFirst and 50 for the third, RetFirst.
From Comment I don't need the actual kpiname from this just the value
The following Query will give you the Answer.
select case column_name when 'rebfirst60' then 60
when 'reifirst1.3' then 1.3
when 'retfirst50' then 50
from employs

I have this now by using the following:
select
SUBSTRING(SUBSTRING(biographytext,1,10),9,2) as RebookingFirst,
SUBSTRING(SUBSTRING(biographytext,11,20),12,3) as ReInventFirst,
SUBSTRING(SUBSTRING(biographytext,21,30),16,3) as ReCreateFirst,
SUBSTRING(SUBSTRING(biographytext,31,40),20,2) as RetentionFirst,
SUBSTRING(SUBSTRING(biographytext,41,50),23,2) as ReferralsFirst
from employs
This gives me the results for each kpi

Related

How to query column with letters on SQL?

I'm new to this.
I have a column: (chocolate_weight) On the table : (Chocolate) which has g at the end of every number, so 30x , 2x5g,10g etc.
I want to remove the letter at the end and then query it to show any that weigh greater than 35.
So far I have done
Select *
From Chocolate
Where chocolate_weight IN
(SELECT
REPLACE(chocolote_weight,'x','') From Chocolate) > 35
It is coming back with 0 , even though there are many that weigh more than 35.
Any help is appreciated
Thanks
If 'g' is always the suffix then your current query is along the right lines, but you don't need the IN you can do the replace in the where clause:
SELECT *
FROM Chocolate
WHERE CAST(REPLACE(chocolate_weight,'g','') AS DECIMAL(10, 2)) > 35;
N.B. This works in both the tagged DBMS SQL-Server and MySQL
This will fail (although only silently in MySQL) if you have anything that contains units other than grams though, so what I would strongly suggest is that you fix your design if it is not too late, store the weight as an numeric type and lose the 'g' completely if you only ever store in grams. If you use multiple different units then you may wish to standardise this so all are as grams, or alternatively store the two things in separate columns, one as a decimal/int for the numeric value and a separate column for the weight, e.g.
Weight
Unit
10
g
150
g
1000
lb
The issue you will have here though is that you will have start doing conversions in your queries to ensure you get all results. It is easier to do the conversion once when the data is saved and use a standard measure for all records.

Round function query 2 to 3 arguments?

I am attempting to find the revenue per distinct user in this query but seem to be running in this error.
select concat('$',format(cast(round(sum(total)/count(distinct(customers))),2)
as int),N'N','en-US')
from table
My error:
The round function requires 2 to 3 arguments
I suspect you mean:
SELECT CONCAT('$',FORMAT(CAST(ROUND(SUM(Total)/COUNT(DISTINCT customers),2) AS int),N'N'),'en-US')
FROM [table];
But, really, worry about the formatting of your values in your presentation layer (The FORMAT and CONCAT don't need to be there).
Also, Why ROUND({expr},2) and then CAST({expr} AS int)? Why not ROUND({expr},0)?
For instance used 2 as length to round
round(sum(total)/count(distinct(customers)),2)

How to use aggregate function to filter a dataset in ssrs 2008

I have a matrix in ssrs2008 like below:
GroupName Zone CompletedVolume
Cancer 1 7
Tunnel 1 10
Surgery 1 64
ComplatedVolume value is coming by a specific expression <<expr>>, which is equal to: [Max(CVolume)]
This matrix is filled by a stored procedure that I am not supposed to change if possible. What I need to do is that not to show the data whose CompletedVolume is <= 50. I tried to go to tablix properties and add a filter like [Max(Q9Volume)] >= 50, but when I try to run the report it says that aggregate functions cannot be used in dataset filters or data region filters. How can I fix this as easy as possible?
Note that adding a where clause in sql query would not solve this issue since there are many other tables use the same SP and they need the data where CompletedVolume <= 50. Any help would be appreciated.
EDIT: I am trying to have the max(Q9Volume) value on SP, but something happening I have never seen before. The query is like:
Select r.* from (select * from results1 union select * from results2) r
left outer join procedures p on r.pid = p.id
The interesting this is there are some columns I see that does not included by neither results1/results2 nor procedures tables when I run the query. For example, there is no column like Q9Volume in the tables (result1, result2 and procedures), however when I run the query I see the columns on the output! How is that possible?
You can set the Row hidden property to True when [Max(CVolume)] is less or equal than 50.
Select the row and go to Row Visibility
Select Show or Hide based on an expression option and use this expression:
=IIF(
Max(Fields!Q9Volume.Value)<=50,
True,False
)
It will show something like this:
Note maximum value for Cancer and Tunnel are 7 and 10 respectively, so
they will be hidden if you apply the above expression.
Let me know if this helps.

Checking Range in Comma Separated Values [SQL Server 2008]

I have a table with following structure
ID FirstName LastName CollectedNumbers
1 A B 10,11,15,55
2 C D 101,132,111
I want a boolean value based on CollectedNumber Range. e.g. If CollectedNumbers are between 1 and 100 then True if Over 100 then False. Can anyone Suggest what would be best way to accomplish this. Collected Numbers won't be sorted always.
It so happens that you have a pretty simple way to see if values are 100 or over in the list. If such a value exists, then there are at least three characters between the commas. If the numbers are never more than 999, you could do:
select (case when ','+CollectedNumbers+',' not like '%,[0-9][0-9][0-9]%' then 1
else 0
end) as booleanflag
This happens to work for the break point of 100. It is obviously not a general solution. The best solution would be to use a junction table with one row per id and CollectedNumber.
Just make a function, which will return true/False, in the database which will convert the string values(10,11,15,55) into a table and call that function in the Selection of the Query like this
Select
ID, FirstName, LastName,
dbo.fncCollectedNumbersResult(stringvalue) as Result
from yourTableName
I think the easiest you can do is build a C# function and use the builtin sqlclr to load it as a custom function you can then call.
Inside the C# function, you can then sort your numbers and make simple logic to return your true/false.

String ending in range of numbers

I have a column with data of the following structure:
aaa5644988
aaa4898494
aaa5642185
aaa5482312
aaa4648848
I have a range that can be anything, like 100-30000 or example. I want to have all values that end in numbers between that range.
I tried
like '%[100-30000]'
but this doesn't work apparently.
I have seen a lot of similar questions but none of the solved my problem
edit I'm using SQL server 2008
Example:
Value
aaa45645695
aaa28568720
aaa65818450
8789212
6566700
For the range 600-1200, I want to retrieve row 1,2,5 because they end with the range.
In SQL, like normally only support % and _ these two operators. That's why like '%[100-30000]' doesn't work.
Depend on your use case, there could be two solutions for this problem:
If you only need to do this query two or three times(didn't care how long it takes), or the dataset is not very big. You can select all the data from this column, and then do the filtering in another programming language.
Take ruby for example, you can do:
column_data = #connection.execute("select * from your_column_name")
result = column_data.map{|x| x.gsub(/^.*[^\d]/, '').to_i }.select{|x| x > 100 && x < 30000}
If you need to do this query regularly, I'd suggest you add a new column to this data table with only the numbers in the current column, so as to get a much better performance in querying speed.
SELECT *
FROM your_table
WHERE number_column BETWEEN 100 AND 30000