Hey I was wondering you know how its possible to use "-" to subtract in the SELECT part of a query. So can you also use "+" to add? I've tried that and instead of adding the values together it does this 123+0.28=1230.28 does that maybe have anything to do with the number being in text format? But I hadn't ever changed format from when i used "-" and that worked . Thanks
my code :
INSERT INTO Table( Question, Calculation)
SELECT DISTINCT 'Addition' AS Question,(T2.Calculation + T1.Calculation) AS Calculation
FROM Some_Table T2, Some_Table T1
ORDER BY T2.Question;
It might be interpreting + as string concatenation between a and b. Try "(a - 0) + (b - 0)" to force interpretation as numbers.
If T2.Calculation and T1.Calculation are text data type, use the Val() function to transform them to numbers before addition.
(Val(T2.Calculation) + Val(T1.Calculation)) AS Calculation
Edit:
When you use the minus operator with two text values (as in "2" - "1"), Access will transform the text values to their numerical equivalents, if possible. However, if either of the text values doesn't represent a valid number, the minus operator will give you a "Type mismatch" error ... as in "2" - "hans"
The plus operator works differently --- with two text values, it will attempt to concatenate them, same as if you'd used the concatenation operator (&) instead of the addition operator (+) ... "2" + "1" will give you "21" as a text value rather than the number 3. So, in that specific case, "2" + "1" is equivalent to "2" & "1".
An important distinction between the addition and concatenation operators is when one of the values is Null. "2" + Null yields Null. But "2" & Null yields "2".
yes, you can use '+' to add two numbers together.
SELECT table1.Field1, table1.Field2, Field1+field2 As SumOfFields
FROM table1;
Field1 Field2 SumOfFields
1 2 3
2 3 5
EDIT:
If you have strings that you want to add together then you need to convert the fields to a number: - since it was pointed out that CLng wouldn't help the OP. It have been changed to CDbl to allow for the decimal.
SELECT table1.Field1, table1.Field2, CDbl(Field1)+CDbl(field2) As SumOfFields
FROM table1;
Just precede your formula with 0+ and it will know you're talking in numbers instead of strings:
Instead of [A]+[B]+[C] put 0+[A]+[B]+[C]
Related
I have a column (RCV1.ECCValue) in a table which 99% of the time has a constant string format- example being:
T0-11.86-273
the middle part of the two hyphens is a percentage. I'm using the below sql to obtain this figure which is working fine and returns 11.86 on the above example. when the data in that table is in above format
'Percentage' = round(SUBSTRING(RCV1.ECCValue,CHARINDEX('-',RCV1.ECCValue)+1, CHARINDEX('-',RCV1.ECCValue,CHARINDEX('-',RCV1.ECCValue)+1) -CHARINDEX('-',RCV1.ECCValue)-1),2) ,
However...this table is updated from an external source and very occasionally the separators differ, for example:
T0-11.86_273
when this occurs I get the error:
Invalid length parameter passed to the LEFT or SUBSTRING function.
I'm very new to SQL and have got myself out of many challenges but this one has got me stuck. Any help would be mostly appreciated. Is there a better way to extract this percentage value?
Replace '_' with '-' to string in CHARINDEX while specifying length to the substring
'Percentage' = round(SUBSTRING(RCV1.ECCValue,CHARINDEX('-',RCV1.ECCValue)+1, CHARINDEX('-',replace(RCV1.ECCValue,'_','-'),CHARINDEX('-',RCV1.ECCValue)+1) -CHARINDEX('-',RCV1.ECCValue)-1),2) ,
If you can guarantee the structure of these strings, you can try parsename
select round(parsename(translate(replace('T0-11.86_273','.',''),'-_','..'),2), 2)/100
Breakdown of steps
Replace . character in the percentage value with empty string using replace.
Replace - or _, whichever is present, with . using translate.
Parse the second element using parsename.
Round it up to 2 digits, which will also
automatically cast it to the desired numeric type.
Divide by 100
to restore the number as percentage.
Documentation & Gotchas
Use NULLIF to null out such values
round(
SUBSTRING(
RCV1.ECCValue,
NULLIF(CHARINDEX('-', RCV1.ECCValue), 0) + 1,
NULLIF(CHARINDEX('-',
RCV1.ECCValue,
NULLIF(CHARINDEX('-', RCV1.ECCValue), 0) + 1
), 0)
- NULLIF(CHARINDEX('-', RCV1.ECCValue), 0) - 1
),
2)
I strongly recommend that you place the repeated values in CROSS APPLY (VALUES to avoid having to repeat yourself. And do use whitespace, it's free.
I have a string column which usually contains integers in two formats... zero-padded, and not:
5
05
I want to sort based on these values numerically. To do that I do something like:
SELECT * FROM things ORDER BY TO_NUMBER(num, '0000');
This works fine, but sometimes there is invalid data, like abc, or !## in this column. Postgres becomes unhappy with me:
ERROR: invalid input syntax for type numeric: " "
What I'd like to do is treat invalid values/failures of TO_NUMBER() as NULL so that they are sorted accordingly. Is this possible? Or, some other alternative?
If you are using PostgreSQL, you can use this query:
SELECT * FROM things ORDER BY
TO_NUMBER((case when num ~ '^[0-9\.]+$' THEN num else '0' end),'0000');
I am trying to extract only the numeric values from a column that contains cells that are exclusively numbers, and cells that are exclusively letter values, so that I can multiply the column with another that contains only numeric values. I have tried
SELECT trim(INTENT_VOLUME)
from A
WHERE ISNUMERIC(INTENTVOLUME)
and also
SELECT trim(INTENT_VOLUME)
from A
WHERE ISNUMERIC(INTENTVOLUME) = 1
and neither works. I get the error Function ISNUMERIC(VARCHAR) does not exist. Can someone advise? Thank you!
It highly depends on DBMS.
in SqlServer you have a limited built-in features to do it, so the next query may not work with all variants of your data:
select CAST(INTENT_VOLUME AS DECIMAL(10, 4))
from A
where INTENT_VOLUME LIKE '%[0-9.-]%'
and INTENT_VOLUME NOT LIKE '%[^0-9.-]%';
In Oracle you can use regex in a normal way:
select to_number(INTENT_VOLUME)
from A
where REGEXP_LIKE(INTENT_VOLUME,'^[-+]?[0-9]+(\.[0-9]+)?$');
MySQL DBMS has also built-in regex
Try this, which tests if that text value can be cast as numeric...
select intent_volume
from a
where (intent_volume ~ '^([0-9]+[.]?[0-9]*|[.][0-9]+)$') = 't'
I have a column that will always be 5 digits long, and each digit will always be a 1 or a 0. I need to put in my where clause to exclude when the second position is equal to 1. For example 01000 is to be excluded but 10010 is to be kept. I currently have:
WHERE (SUBSTRING(field, 2, 1) <> '1') or field IS NULL
How do do this without using the Substring function?
Edit:Also, the column is a varchar(10) in the database. Does this matter?
You could use the like operator to check that character directly:
WHERE field LIKE '_1%' OR field IS NULL
Use LEFT and RIGHT and then check that is 1 or not as below-
WHERE RIGHT(LEFT(field,2),1) <> '1' OR field IS NULL
No.
If 'field' is of a string type, you need to use string functions to manipulate it. SUBSTRING or some other flavor of it.
You can also convert it to binary and use bitwise AND operator but that won't solve the root issue here.
You are facing the consequences of someone ignoring 1NF.
There is a reason why Codd insisted that every "cell" must be atomic. Your's is not.
Can you separate this bitmap into atomic attribute columns?
I was helping a co-worker debug a query that was returning weird results. We narrowed it down to a line that looked like this:
WHERE COL BETWEEN '11201' AND '111226'
The value in COL comes from a call to substring, so it's a string type value. This returns no results.
Naively, I had always assumed that BETWEEN represented >= and <= and that if you call it with strings, it would cast everything to numerical type values. That works just fine if you have something like:
WHERE COL BETWEEN '11201' AND '11226'
Which returns results in the case we are using it.
Clearly, since the second snippet returns results but the first snippet does not, my understanding is mistaken.
I cast everything to numbers and tried it again, and got the expected behavior. From this, it seems like I can conclude that when it does string comparisons, it actually doesn't cast the values - instead, it goes character by character. When it gets to the third character and sees 2 > 1 in the lower bound argument, it quits based on the following behavior from the Oracle documents:
If expr3 < expr2, then the interval is empty.
Can anyone weigh in on if this is what is truly happening beneath the hood?
Thank you!
The expression:
WHERE COL BETWEEN '11201' AND '111226'
is the same as:
WHERE COL >= '11201' AND COL <= '111226'
This returns nothing because -- as strings -- '11201' > '111226'. This uses alphabetic ordering, so this would be clearer if you used letters:
WHERE COL BETWEEN 'BBCAB' AND 'BBBCCG'
Clearly, there is nothing alphabetic between these values, because 'BBC' occurs after 'BBB'.
The moral? If you want comparisons that are intuitive, use the right types.
In the expression below
WHERE COL BETWEEN '11201' AND '111226'
You are comparing a text column COL against text. The string '11201' is lexicographically greater than the string '111226'. In other words, '11201' comes after '111226' in the dictionary, or the former is greater than the latter. This is why no results are coming back. However, if you cast COL to a number, and compare that to numbers, then the comparison might work, assuming there are matching records:
WHERE TO_NUMBER(COL) BETWEEN 11201 AND 111226