How to remove a leading character from numeric string? SQL - sql

I have a list of tournament results from PGA tour data and would like to remove the "T" from the beginning of the finish column strings where applicable, so that I can get an average number. The string lengths are variable and also contain "CUT" in some rows. Is there a way to remove the "T"?
I have used...
WHERE Finish not like "CUT"
to remove "CUT" values
and have used various functions with no success to remove the "T". Any help would be greatly appreciated! Thanks
Showing variable string lengths in Finish column
EDIT:
This is what I have so far, which works perfectly to aggregate averages and group by player in a single row as desired.
SELECT
DISTINCT(player),
ROUND(AVG(CAST(sg_putt as numeric)),2) as avg_sg_putt,
ROUND(AVG(CAST(sg_arg as numeric)),2) as avg_sg_arg,
ROUND(AVG(CAST(sg_app as numeric)),2) as avg_sg_app,
ROUND(AVG(CAST(sg_ott as numeric)),2) as avg_sg_ott,
ROUND(AVG(CAST(sg_t2g as numeric)),2) as avg_sg_t2g,
ROUND(AVG(CAST(sg_total as numeric)),2) as avg_sg_total,
SUM(made_cut) as cuts_made,
COUNT(DISTINCT(tournament_id)) as total_played,
FROM
`pga_stats_2015_2022.stats`
WHERE
season >= 2017 AND
sg_putt not like "NA" AND
sg_arg not like "NA" AND
sg_app not like "NA" AND
sg_ott not like "NA" AND
sg_t2g not like "NA" AND
sg_total not like "NA"
GROUP BY player
HAVING total_played > 50
ORDER BY(avg_sg_total) DESC

From the documentation here, it seems you want REPLACE:
REPLACE(original_value, from_value, to_value)
So for instance,
SELECT REPLACE(Finish,'T','') as Finish
FROM yourTable
WHERE Finish <> 'CUT'
EDIT:
Looking at your full query, I suspect you want to add:
ROUND(AVG(CAST(REPLACE(Finish,'T','') as numeric)),2) as avg_Finish
to your SELECT.
Then add:
WHERE Finish <> "CUT"
to your WHERE

Perhaps ltrim does the trick
select ltrim(finish,'T') --might want to cast to int before calculating avg
from..
where..
Note that ltrim removes all occurrences from the left so it'll remove T from both T6 and TT6 for example

Related

ORACLE sql Substr / Instr

I have a column within a table that has PO-RAILCAR. I need to split this column into two. I write the following query and it does exactly what I want. However, the results come back with the dash. How do I write it to return the values as they are without the dashes?
SELECT INVT_LEV3, SUBSTR(INVT_LEV3,1,INSTR(INVT_LEV3,'-')) AS PO,
SUBSTR(INVT_LEV3,INSTR(INVT_LEV3,'-')) AS Railcar
FROM C_MVT_H
WHERE INVT_LEV4 = 'G07K02129/G07K02133'
This is what I get: First column is the column I need to split. The second and third look perfect but I need the dash removed
Column 1: 110799P-FBOX50553 Column2: 110799P- Column3:-FBOX505536
The problem is occurring because INSTR is giving you the position of the '-' within the text. To fix this you can just add or subtract 1 from the position returned.
Your current query:
SELECT INVT_LEV3, SUBSTR(INVT_LEV3,1,INSTR(INVT_LEV3,'-')-1) AS PO, SUBSTR(INVT_LEV3,INSTR(INVT_LEV3,'-')+1) AS Railcar FROM C_MVT_H WHERE INVT_LEV4 = 'G07K02129/G07K02133'
Proposed new query
SELECT INVT_LEV3, SUBSTR(INVT_LEV3,1,INSTR(INVT_LEV3,'-')) AS PO, SUBSTR(INVT_LEV3,INSTR(INVT_LEV3,'-')) AS Railcar FROM C_MVT_H WHERE INVT_LEV4 = 'G07K02129/G07K02133'

Adding column to table based on whether another column = a specific string

I want to add a column called "Sweep" that contains bools based on whether the "Result" was a sweep or not. So I want the value in the "Sweep" column to be True if the "Result" is '4-0' or '0-4' and False if it isn't.
This is a part of the table:
I tried this:
ALTER TABLE "NBA_finals_1950-2018"
ADD "Sweep" BOOL;
UPDATE "NBA_finals_1950-2018"
SET "Sweep" = ("Result" = '4-0' OR "Result" = '0-4');
But for some reason, when I run this code...:
SELECT *
FROM "NBA_finals_1950-2018"
ORDER BY "Year";
...only one of the rows (last row) has the value True even though there are other rows where the result is a sweep ('4-0' or '0-4') as shown in the picture below.
I don't know why this is happening but I guess there is something wrong with the UPDATE...SET code. Please help.
Thanks in advance.
NOTE: I am using PostgreSQL 13
This would occur if the strings are not really what they look like -- this is often due to spaces at the beginning or end. Or perhaps to hyphens being different, or other look-alike characters.
You just need to find the right pattern. So so with a select. This returns no values:
select *
from "NBA_finals_1950-2018"
where "Result" in ('4-0', '0-4');
You can try:
where "Result" like '%0-4%' or
"Result" like '%4-0%'
But, this should do what you want:
where "Result" like '%4%' and
"Result" like '%0%'
because the numbers are all single digits.
You can incorporate this into the update statement.
Note: double quotes are a bad idea. I would recommend creating tables and columns without escaping the names.

MS Access Expression to Find Records Where the Value to the Left of a Comma is Greater than Zero

I have some records in a column that contain IDs and some of these records contain multiple IDs separated by commas. Additionally there are some records where I have ",3" and ",2" when they should simply be "3" and "2". I do not have write privileges in this DB so updating those records is not an option.
I am trying to write a query that returns records that have a comma where the value to the left of any comma in the record is greater than 0 e.g. "2,3", "2,3,12" etc but NOT ",3" or ",2".
What would this expression look like in MS Access?
Thanks in advance.
If you want to remove the starting comma from the records when you return them, you can do so using a simple query:
SELECT IIF(MyField LIKE ",*", Right(MyField, Len(MyField)-1), MyField)
FROM MyTable
To answer your original question, you could simply use Val:
SELECT * FROM YourTable WHERE Val([YourField]) > 0
I would simply use:
select t.*
from t
where val not like ",*";
This doesn't handle the 0 part, but you don't give any examples in your answer. Perhaps this answers that part:
select t.*
from t
where val not like ",*" and val not like "*0,*";

Natural or Human Sort order

I have been working on this on for months. I just cannot get the natural (True alpha-numeric) results. I am shocked that I cannot get them as I have been able to in RPG since 1992 with EBCDIC.
I am looking for any solution in SQL, VBS or simple excel or access. Here is the data I have:
299-8,
3410L-87,
3410L-88,
420-A20,
420-A21,
420A-40,
4357-3,
AN3H10A,
K117GM-8,
K129-1,
K129-15,
K271B-200L,
K271B-38L,
K271D-200EL,
KD1051,
KD1062,
KD1092,
KD1108,
KD1108,
M8000-3,
MS24665-1,
SK271B-200L,
SAYA4008
The order I am looking for is the true alpha-numeric order as below:
AN3H10A,
KD1051,
KD1062,
KD1092,
KD1108,
KD1108,
K117GM-8,
K129-1,
K129-15,
MS24665-1,
M8000-3,
SAYA4008,
SK271B-200L
The inventory is 7800 records so I have had some problems with processing power as well.
Any help would be appreciated.
Jeff
In native Excel, you can add multiple sorting columns to return the ASCII code for each character, but if the character is a number, then add a large number to the code (e.g 1000).
Then sort on each of the helper columns, including the first column in the table, but not in the sort.
The formula:
=IFERROR(CODE(MID($A1,COLUMNS($A:A),1))+AND(CODE(MID($A1,COLUMNS($A:A),1))>=48,CODE(MID($A1,COLUMNS($A:A),1))<=57)*1000,"")
The Sort dialog:
The results:
You can implement a similar algorithm using VBA, and probably SQL also. I dunno about VBS or Access.
You could try using format for left padding the string in order by
select column
from my_table
order by Format(column, "0000000000")
Add a sorting column:
, iif (left(fieldname, 1) between '0' and '9', 1, 0) sortField
etc
order by sortField, FieldName
Lets say you have your data in column "A". If you put this formula in column "B" =IFERROR(IF(LEFT(A1,1)+1>0,"ZZZZZZZ "&A1,A1),A1), it will automatically add Z in front of all numerical values, so that they will naturally appear after all alphabetical values when you sort A-Z. later you can find&replace that funny ZZZZZZ string...
There a number of approaches, but likely the least amount of work is to build two columns that split out the delimiter (-) in this case.
You then “pad” the results (spaces, or 0) right justified, and then sort on the two columns.
So in the query builder we have this:
SELECT Field1,
Format(
Mid(field1,1,IIf(InStr(field1,"-")=0,50,InStr(field1,"-")-1)),
">##########") AS Expr1,
Format(
Mid(field1,IIf(InStr(field1,"-")=0,99,InStr(field1,"-")+1)),
">##########") AS Expr2
FROM Data
When we run the above raw query we get this:
So now in the query builder, simply sort on the first derived column, and then sort on the 2nd derived column.
Eg this:
Run the query, and we get this result:
Edit:
Looking at you desired results, it looks like above sort is wrong. We have to RIGHT just and pad with 0’s.
So this 2nd try:
SELECT Field1,
Left(Mid(field1,1,IIf(InStr(field1,"-")=0,30,InStr(field1,"-")-1))
& String(30,"0"),30) AS Expr1,
Left(Mid(field1,IIf(InStr(field1,"-")=0,99,InStr(field1,"-")+1))
& String(30,"0"),30) AS Expr2
FROM Data
The results are thus this:
Given your small table size, then the above query should perform quite well.

Sorting data in Access database where the column has numbers and letters

Please help me because I have been unable to get this right.
What is the access SQL to select this column(columnA) so that it returns a resultset with distinct values sorted first according to numbers and then to letters.
Here is the columns values: {10A,9C,12D,11G,9B,10C,9R,8T}
I have tried 'Select distinct ColumnA from tblClass order by 1'
but it returns {10A,10C,11G,12D,8T,9B,9C,9R} which is not what I want.
Thank you in advance.
You can use the Val() function for this. From the help topic: "The Val function stops reading the string at the first character it can't recognize as part of a number"
Val(10A) will give you 10, Val(9C) will give you 9, and so on. So in your query, order by Val(ColumnA) first, then ColumnA.
SELECT DISTINCT Val([ColumnA]) AS number_part, ColumnA
FROM tblClass
ORDER BY Val([ColumnA]), ColumnA;
SELECT DISTINCT ColumnA
FROM tblClass
ORDER BY CInt(LEFT(ColumnA,len(ColumnA)-1)), RIGHT(ColumnA,1);
If there last character is a letter and the others are a number.
Your data type is a string so it's sorting correctly, to get the result you want you're going to have to split your values into numeric and alphabetic parts and then sort first on the numeric then the alphabetic. Not being an Access programmer I can't help you with exactly how you're going to do that.
order by 1?
Don't you mean order by ColumnA?
SELECT DISTINCT ColumnA
FROM tblClass
ORDER BY ColumnA
I had a similar problem and used a dummie workaround:
changing a list of {10A,10C,11G,12D,8T,9B,9C,9R}
into {10A,10C,11G,12D,08T,09B,09C,09R} by adding the 0 before each <10 number.
now all items are the same length and access will sort correctly into {08T, 09B, 09C, 09R, 10A, 10C, 11G, 12D}
.
To achieve this, I copied this column into excel column A and used IF(LEN(A2)<3, concatenate("0", A2))