How to use count(*) and Division Operation in SQL statements - sql

I'm loading big data into database,
i want to know how this process going.
i use
select count(*) from table
to check how many rows loaded.
and now i want to get a Percentage of the process.
i tried:
select ( count(*)/20000 ) from table
and
select cast( ( count(*)/20000 ) as DECIMAL(6,4) ) from table
but they all return 0 ,
so how can i do this?
And better if it can show the percentage .
thanks

Integer division returns an integer, the decimal part is truncated. You could divide by 20000.0:
select ( count(*)/20000.0 ) from table
Demo
MSDN / (Divide)
If an integer dividend is divided by an integer divisor, the result is
an integer that has any fractional part of the result truncated.

Select CONVERT(DECIMAL(6,4),COUNT(*)) / CONVERT(DECIMAL(6,4),20000) FROM TABLE
-
Its important that you match the type explicitly because not all numbers are integers and not all decimals are the same. DECIMAL(6,4) is effectively its own data type which is not the same as DECIMAL(6,3).

Related

How to extract a part of a decimal in Hive

I have two columns called quantity and price. Quantity is divided by price. If the result contains decimal, I want the number before the decimal. Or else, the number as it is.
I think you are looking for:
select floor(quantity / price) as output
Casting issues?
select cast(quantity / price as bigint)
By the way, I think you may want this:
Hive Data Types Manual
Also DIV operator can be used (for integer arguments):
with your_data as (
select stack(3, 13,2,8,2,233,2) as(quantity,price)
)
select quantity div price
from your_data d
;
Result:
6
4
116

Trim a decimal to 2 places Bigquery

I am currently running a query that runs a sum function and also divides this number. Currently I get values like 0.0904246741698848, and 1.6419814808335567. I want these decimals to be trimmed to 2 spaces past the decimal point. Their schema is a float. Here is my code. Thanks for the help.
#standardSQL
SELECT
Serial,
MAX(createdAt) AS Latest_Use,
SUM(ConnectionTime/3600) as Total_Hours,
COUNT(DISTINCT DeviceID) AS Devices_Connected
FROM `dataworks-356fa.FirebaseArchive.Firebase_ConnectionInfo`
WHERE PeripheralType = 1 or PeripheralType = 2 or PeripheralType = 12
GROUP BY Serial
ORDER BY Latest_Use DESC
#standardSQL
WITH `data` AS (
SELECT 0.0904246741698848 AS val UNION ALL
SELECT 1.6419814808335567
)
SELECT val, ROUND(val, 2) AS rounded_val
FROM `data`
for example, assuming your want apply this to your Total_Hours column :
#standardSQL
SELECT
Serial,
MAX(createdAt) AS Latest_Use,
ROUND(SUM(ConnectionTime/3600),2) AS Total_Hours,
COUNT(DISTINCT DeviceID) AS Devices_Connected
FROM `dataworks-356fa.FirebaseArchive.Firebase_ConnectionInfo`
WHERE PeripheralType = 1 OR PeripheralType = 2 OR PeripheralType = 12
GROUP BY Serial
ORDER BY Latest_Use DESC
I found that rounding was problematic if my data had a whole number such as 2.00 and I needed all of my data to reflect 2 decimal places as these were for prices that end up getting displayed. Big Query was returning 2.0 no matter what I specified to round to using ROUND.
Assuming you're working with data that never surpasses 2 decimal places, and it is stored as a STRING, this code will work (if it's more decimal places, add another 0 to the addition for each space).
FORMAT("%.*f",2,CAST(GROSS_SALES_AMT AS FLOAT64) + .0001)
This will take a float in BigQuery and format it with two decimal points.
CAST(SUM(ConnectionTime/3600) AS STRING FORMAT '999,999.99')
Note: Add a a currency symbol (e.g., $) for currency ($999,999.99).
Example:
You can always use the round() function.
If you are looking for precision after decimal (as using round will round-off the values) you can use substr(str(value),precision) which will give exact output after decimal.

AVG function not working

I am working on SQL Server. I have a table that has an int column HalfTimeAwayGoals and I am trying to get the AVG with this code:
select
CAST(AVG(HalfTimeAwayGoals) as decimal(4,2))
from
testtable
where
AwayTeam = 'TeamA'
I get as a result 0.00. But the correct result should be 0.55.
Do you have any idea what is going wrong ?
select
AVG(CAST(HalfTimeAwayGoals as decimal(4,2)))
from
testtable
where
AwayTeam = 'TeamA'
If the field HalfTimeAwayGoals is an integer, then the avg function does an integer average. That is, the result is 0 or 1, but cannot be in between.
The solution is to convert the value to a number. I often do this just by multiplying by 1.0:
select CAST(AVG(HalfTimeAwayGoals * 1.0) as decimal(4, 2))
from testtable
where AwayTeam = 'TeamA';
Note that if you do the conversion to a decimal before the average, the result will not necessary have a scale of 4 and a precision of 2.
Can you try dividing by 1.00 to convert the integer into decimal?
select
AVG(HalfTimeAwayGoals/1.00) as average
from
testtable
where
AwayTeam = 'TeamA'
I used the /1.00 OR /1.0000 trick on various databases to do the job. Unfortunately, I don't have access MS-SQL to try it. The division of integer by 1.00 will change the integer to decimal.
SELECT AVG(integerfield/1.00) FROM table
In MySQL
SELECT AVG(integerfield) FROM table
gives me 4 decimal points.
If I do
SELECT AVG(integerfield/1.00) FROM table
I get 8 decimal points.

Division of integers returns 0

I feel like I'm missing something obvious. I am trying to test out the distribution of random(). Here is the table:
create table test (
id int,
random_float float,
random_int int
);
Here is what I want to do:
truncate table test;
insert into test (id)
values (generate_series(1,1000));
update test
set
random_float = random() * 10 + 1;
update test
set
random_int = trunc(random_float);
select
random_int,
count(random_int) as Count,
cast( count(random_int) / max(id) as float) as Percent
from test
group by random_int
order by random_int;
However, the "Percent" column returns zero for every record. I tried casting it as float, as decimal, I tried changing the random_int column to decimal instead of integer, always same result.
Here is a fiddle.
Any insight as to what I am doing wrong?
You should cast before you divide, but also you were missing a subquery to get the total count from the table. Here's the sample.
select
random_int,
count(random_int) as Count,
cast(count(random_int) as decimal(7,2)) / cast((select count(random_int) from test) as decimal(7,2)) as Percent
from test
group by random_int
order by random_int;
Try this query instead:
select
random_int,
count(random_int) as Count,
cast( count(random_int) / max(id) as float) as Percent,
(100.0 * count(random_int) / max(id))::numeric(5,2) as pct
from test
group by random_int
order by random_int;
PostgreSQL has a strong types system. In your case, type is implied by count() function, which returns bigint (or int8) and id column, which is integer.
I would recommend using 100.0 as initial multiplier, that'll cause whole expression to be calculated as numeric and will also provide real percents. You might also want to cast to numeric(5,2) at the end to get rid of too big number.

sql where condition for int but column type is Varchar

I have table called Buttons. Buttons table i have column button_number . Table contain more than 100 records. Now i have to select a buttons number between 10 to 50. When i used this following query it's not returning zero row.
select * from Buttons where button_number >= '10' and button_number <='50'
What's the problem in the query. If i use the same query with different column(data type is int) then it's working fine. Is the problem because of the data type of the column? If so what's the fix for this?
Note : button_number column data type is Varchar.
The button_number is varchar and you are trying to do an integer style comparison. You will need to cast the button_number column to an integer.
select * from Buttons where
convert(integer, button_number) >= 10 and convert(integer, button_number) <= 50
Edit
The above query will require a table scan since it needs to convert every button_number to an integer before applying the where clause. This isn't a problem for 100 rows, but would be an issues for large numbers.
As mentioned in Mikael Eriksson's answer, a better alternative would be to change the type of button_number to an integer type (if possible). This would have several advantages:
There would be no chance of entering a non-integer value in the column
You would then be able to apply an integer index to the column. This would greatly improve the speed of your query when the table contains large numbers of rows.
If so what's the fix for this?
The other answers tells you to cast the column to int in the query. That will work for you if you only have integers in the column. If that is the case you should change the data type for column button_number to int so you don't risk having a character value in there that will break your query.
modify your query like below
select * from Buttons where cast(button_number as int) >= 10 and cast(button_number as int) <=50
but make sure that all the values of column "button_number" dont have any charcters
Depending on your DB type and your version, but in MySQL you might need to use SIGNED or UNSIGNED as your datatype:
SELECT * FROM Buttons
WHERE CONVERT(SIGNED, button_number) >= 10
AND CONVERT(SIGNED, button_number) <= 50
In postgreSQL database you can convert like this :
select * from Buttons where
button_number::int >= 10 and convert(integer, button_number) <= 50