ROUND function in ODBC - sql

I am working on a third-party custom flat file DB that I access through ODBC and the ROUND function is throwing errors always.
Is there a function that can do rounding in ODBC?
An example that throws an error:
SELECT AUDIT_SPLIT.ACCOUNT_REF, ROUND(SUM(AUDIT_SPLIT.GROSS_AMOUNT), 2) FROM AUDIT_SPLIT GROUP BY AUDIT_SPLIT.ACCOUNT_REF
Though Excel the error is "Column not found"

So I will try something like this:
SELECT A.ACCOUNT_REF, ROUND(SUM(A.GROSS_AMOUNT), 2) GROSS_AMOUNT_SUM
FROM AUDIT_SPLIT A
WHERE A.ACCOUNT_REF IS NOT NULL AND A.GROSS_AMOUNT IS NOT NULL
GROUP BY 1

Is your flat file something like a csv, a delimited text file or a fixed length file?
In this case I will suggest to check for the last line is not empty.
If the file ends with a cr/lf a new line is added and it is filled with nulls.
Also, from which client are you running the query? You have not given a name to ROUND() column, maybe you need it.
So I will try something like this:
SELECT A.ACCOUNT_REF, ROUND(SUM(A.GROSS_AMOUNT), 2) AS GROSS_AMOUNT_SUM
FROM AUDIT_SPLIT A
WHERE A.ACCOUNT_REF IS NOT NULL AND A.GROSS_AMOUNT IS NOT NULL
GROUP BY A.ACCOUNT_REF
UPDATE
Maybe the problem is related to the comma present in ROUND function, because it is interpreted as a column separator, you can avoid it using ODBC escape clause {fn ROUND()} (as suggested by jarlh in his comment), and to be sure and clear I will try to split the SUM() and the ROUND() in this way:
SELECT S.ACCOUNT_REF, {fn ROUND(S.GROSS_AMOUNT_SUM, 2)} AS ROUNDED_SUM
FROM (
SELECT A.ACCOUNT_REF, SUM(A.GROSS_AMOUNT) AS GROSS_AMOUNT_SUM
FROM AUDIT_SPLIT AS A
WHERE A.ACCOUNT_REF IS NOT NULL AND A.GROSS_AMOUNT IS NOT NULL
GROUP BY A.ACCOUNT_REF
) AS S

Related

How can I use an SQL aggregate function on data I directly input at the command line (e.g. AVG(1, 2, 3))?

How can I enter multiple values into an aggregate function using just data I enter at the command line? Say, in Postgres, I run the following.
SELECT AVG(2);
I'll get the correct answer, but I can't find a way to enter multiple values, such as below, without getting an error.
SELECT AVG(1,NULL,2,3);
I've tried wrapping the numbers in various brackets but to no effect. What's the syntax I'm missing?
EDIT: Additionally, is there a way to include NULLs in the input?
AVG() is an aggregate that operates over multiple rows. So you need to convert your comma separated list to one row per value to be able to use an aggregate like avg(). This could be done using e.g. string_to_table
select avg(num::numeric)
from string_to_table('1,2,3', ',') as x(num)
If you want to include a NULL value, you could add it to the list and convert it to null before casting it to a numeric value:
select avg(nullif(num, 'null')::numeric)
from string_to_table('1,2,3,4,null', ',') as x(num)

How to reference a column in SQL that has count?

How do I get the column "count(division)" instead of getting the actual number of counts?
select * from num_taught;
gets me this
select count(division) from num_taught;
gets me this, but I actually want the third column "count(division)" from the previous image
I want to know this because I'm doing this right now:
sql> select * from num_taught as a, num_taught as b
...> where a.count(division) = b.count(division);
Error: near "(": syntax error
but as you can see, there's a syntax error and I think it's because the code is not referencing the "count(division)" columns but actually finding the count instead.
My end goal is to output the "Titles" that have the same "Division" and have the same count(division).
So for example, the end table would have the rows "Chief Accountant", "Programmer Trainee", "Scrivener", "Technician", "Wizard". Since these are the rows that have a match in division and count(division)
Thanks!
What does DESC num_taught return? I am curious how the third column is populated - is it some kind of pseudo-column? You may want try wrapping the column name with [], see: How to deal with SQL column names that look like SQL keywords?
i.e. try:
select [count(division)] from num_taught;
You need to escape your column name using quotes (in case it's Sqlite like you mentioned in the comments).
select "count(division)" from num_taught;
or:
select * from num_taught as a, num_taught as b
where a."count(division)" = b."count(division)";
If you don't you are using the count-function provided by your Database-system.
It's very unusual to name a column like this, it might be either a trap by your tutor or an error while initializing the table in your case.
I think you just want a count(distinct):
select count(distinct division)
from num_taught;

How to extract numeric values from a column in SQL

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'

converted data type (varchar) still shows conversion error

I have a column that can store text but is used to store a number (I did not make the system!) someone has put a blank value in (i.e. not content but not null) and its causing error: -
Msg 8114, Level 16, State 5, Line 1
Error converting data type varchar to numeric.
I have reduced the issue down to the below: -
SELECT
T1.[FIELD_5],
ISNUMERIC(T1.[FIELD_5]),
NULLIF(T1.[FIELD_5],''),
ISNULL(NULLIF(T1.[FIELD_5],''),0),
CONVERT(DECIMAL(18,5),ISNULL(NULLIF(T1.[FIELD_5],''),0))
FROM
[MyTBL] T1
ORDER BY
ISNUMERIC(T1.[FIELD_5])
The issue data is in [FIELD_5]
I can see SQL sees a value as not numeric
I can see that NULLIF is successfully changing it to a NULL value
I can see the ISNULL is turning the NULLIF result to 0
But the CONVERT on the ISNULL result results in the error message, I would expect it to result in 0.00000
Use try_convert():
SELECT T1.[FIELD_5], ISNUMERIC(T1.[FIELD_5]), NULLIF(T1.[FIELD_5], ''),
COALESCE(NULLIF(T1.[FIELD_5], ''), 0),
TRY_CONVERT(DECIMAL(18, 5), COALESCE(NULLIF(T1.[FIELD_5], ''), 0))
FROM [MyTBL] T1
ORDER BY ISNUMERIC(T1.[FIELD_5]);
try_convert() was introduced in SQL Server 2012. If you are using an earlier version, then you need to use a case expression.
(I switched ISNULL() to COALESCE() because I prefer to use ANSI standard functions where practical.)
There is some non numeric value available you can do that check with case as below:
select convert(decimal(18,5), '')
Throws error as "Error converting data type varchar to numeric.
"
SELECT
T1.[FIELD_5],
ISNUMERIC(T1.[FIELD_5]),
NULLIF(T1.[FIELD_5],''),
ISNULL(NULLIF(T1.[FIELD_5],''),0),
CONVERT(DECIMAL(18,5), iif(isnumeric(ISNULL(T1.[FIELD_5]),'0') > 1,T1.[FIELD_5],'0')
ISNULL(NULLIF(T1.[FIELD_5],''),0))
FROM
[MyTBL] T1
ORDER BY
ISNUMERIC(T1.[FIELD_5])
This was a case of better investigation was needed, I should have realised as in my opinion SQL doesn't lie its normally always user error.
I run it again without the order by clause and then selected the row that would have shown up after the last row that did show up (i.e. that row that caused the error).
[FIELD_5] contained the value 1E-07, an infamous bad import from Excel!
What doesn't add up is why when I had the order by ISNUMERIC on, I did not see this value at the top of the list, only the blank values that were indeed being managed properly.
Question solved, I should have stuck investigating but I think this is worth leaving up to help other investigate in the future.

how to use substr in SQL Server?

I have the following extract of a code used in SAS and wanted to write it in SQL Server to extract data.
substr(zipname,1,4) in("2000","9000","3000","1000");run;
How do I write this in SQL Server ?
I tried and got this error:
An expression of non-boolean type specified in a context where a
condition is expected
In sql server, there's no substr function (it's substring)
by the way, you need a complete query...
select blabla
from blibli
where substring(zipname, 1, 4) in ('2000', '9000', 3000', '1000')
assuming zipname is a varchar or something like that...
You need a table that you are getting the records from, and zipname would be a column in the table. The statement would be something like this:
select * from tablename where substring(zipname,1,4) in ('2000','9000','3000','1000')
Since you want the first x characters, you can also use the left() function.
where left(zipname, 4) in (values go here)
Bear in mind that your values have to be single quoted. Your question has double quotes.