Very new and learning SQL. Trying to calculate a percentage from two columns as such:
Select (total_deaths/total_cases)*100 AS death_percentage
From covid_deaths
I’m getting the column but it’s showing as an Integer and all values are zero.
I’ve tried using CAST to make it a decimal but i don’t have the syntax right. Very noob question but seems simple enough. Do I have to declare the numeric type of all calculated columns?
In addition to the answer linked by Stefan Zivkovik in a comment above, it may be good to handle division by zero. Even if you don't ever anticipate total_cases will be zero, someone may reuse this part of the code (for instance, if total_cases is later broken into subcategories).
You probably also want to ROUND to a certain number of decimal places
SELECT
CASE WHEN total_cases > 0 THEN
ROUND((total_deaths::NUMERIC/total_cases)*100,1)
END AS death_percentage
FROM covid_deaths
By not specifying an ELSE clause, the column will be null when total_cases is zero. If this doesn't work for your purposes, you could specify another default value (like zero) with ELSE.
Related
I'm doing a report from our database regarding some amount
It shows like this in the report from the front end
however in the backend it's like this
It seems that the system adds a decimal point before the last two digits of the entries I've check the other ones and this seems to be the case
My question is, is there a function that I can use to append a decimal point before the last two digits whenever I generate the report in postgres?or is there another way to achieve the same result?
So I can provide a backend report that shows the same as the front end
Assuming the amount values are actually in cents, you should be able to just divide by 100:
SELECT expense_date, CAST(amount / 100.0 AS money) AS money
FROM yourTable;
Also, you may wish to handle this formatting issues in your presentation layer rather than directly on Postgres.
I have a column of type bigint (ProductSerial) in my table. I need to filter the table by the Product serial using like operator. But I found that, like operator can't be used for integer type.
Is there any other method for this (I don't want to use the = operator).
If you must use LIKE, you can cast your number to char/varchar, and perform the LIKE on the result. This is quite inefficient, but since LIKE has a high potential of killing indexes anyway, it may work in your scenario:
... AND CAST(phone AS VARCHAR(9)) LIKE '%0203'
If you are looking to use LIKE to match the beginning or the end of the number, you could use integer division and modulus operators to extract the digits. For example, if you want all nine-digit numbers starting in 407, search for
phone / 1000000 = 407
Although I'm a bit late to the party, I'd like to add the method I'm using to match the first N given numbers (in the example, 123) in any numeric-type column:
SELECT * FROM MyTable WHERE MyColumn / POWER(10, LEN(MyColumn) - LEN(123)) = 123
The technique is similar to #dasblinkenlight's one, but it works regardless of the number of digits of the target column values. This is a viable workaround if your column contain numbers with different length and you don't want to use the CAST+LIKE method (or a calculated column).
For additional details on that (and other LIKE workarounds) check out this blog post that I wrote on this topic.
If you have control over the database you could add a calculated column to copy the integer value to a string:
ALTER TABLE MyTable
ADD CalcCol AS (CAST(ProductSerial AS VARCHAR)) PERSISTED
And query like:
SELECT *
FROM MyTable
WHERE ProductSerial LIKE '%2548%'
This will move the calculation to the insert/update and only on rows inserted/updated rather then converting every row for each query.
This may be a problem if there are a lot of updated to columns as it will add a very small overhead to these.
There may be a way to do it mathematically using modulus but this would take a lot of working out and testing.
You can change your Field PhoneNumbers and store as String and then use the Like You can alter your table so that you can use the LIKE statement, if you still want to use BIGint for your phone numbers, you cannot get the exact Phone Number without using = the method you can use is Between method that looks for the Numbers that are inside the range.
For the edited question: I think you should use = sign for their ID, or convert the Int to String and then Use Like.
The original question related to a phone number. OP has since edited it to refer to serial numbers. This answer refers to the original question only.
My suggestion is to avoid storing your phone numbers as integers in the first place, and thus the problem does not occur. My phone number is in the form, internationally, of:
+44 7844 51515
Storing it as an integer makes no sense here, as you will never need to do any mathematical operation on it, and you would lose the leading plus. Within the UK, it is:
07844 51515
and thus storing it as an integer would lose its leading zero. Unless you have a very very specific requirement to store it as an integer, you would fare significantly better storing it as a string instead.
[Note: Not actually my phone number]
When I try to get the difference between two apparently equal numbers, I get a number different than zero.
product_price min_product_price price_dif
40,609756097561 40,609756097561 -2,1316282072803E-14
I understand this can be a difficult question to answer without all the queries that lead to this, but I'll try to explain,
product_price comes straight from the ERP database.
min_product_price is obtained with a
MIN(ItemSellingPrices.UnitPrice) as min_product_price
together with a group by clause. Shouldn't this mean the numbers are the same?
I have no experience with this kind of issues, so I apologize if this is too basic.
Looks like a floating point issue.
If you're storing money values in float or real columns, try using a decimal/numeric data type instead.
For storing 12 decimal values, you could use decimal(18, 12), for example.
Query:
SELECT StartDate, EndDate, RIGHT(Sector, 1 )
FROM Table1
ORDER BY Right(Sector, 1), StartDate
By looking at this, the query should order everything by sector, followed by the start date. This query has worked for quiet awhile until yesterday where it did not order it properly, for some reason, Sector 2 came before Sector 1.
The data type for Sector is of type int, not null. After inserting a TRIM function into Sector it seems to work fine afterwards.
New Query:
SELECT StartDate, EndDate, RIGHT(Sector, 1 )
FROM Table1
ORDER BY Right(TRIM(Sector), 1), StartDate
Which I found really weird since it's suppose to only pick out one character, so why is there leading spaces?
Is there an issue with using RIGHT function on a int before converting the type? Or is it something else?
Thanks for the help everyone!
-Edit- The RIGHT function should return either 1,2,3 or 4 however when ordering it, 2 comes before 1.
To clarify, the column Sector contains an int value, we can determine it's location by obtaining the last digit (Which is why the previous coder did)
MS Access 2003 has a curious little feature (I can't speak for the other versions):
Make a simple query. Sort by Column A Ascending. Save the query.
Run the query. When you see the output, sort by Column A Descending using the toolbar option (see pic below). Save & close.
Run the query again. Your new sort will have overridden the sort that you saved in the query.
I think you or someone else probably just opened the query out of curiosity, sorted by Sector Descending, and when prompted to save Design Changes, you chose Yes (even though technically you didn't make any). The easiest way I found to restore the original sort is to edit the query and save it.
You've got your data stored wrong if you need to sort on a subcharacter of a numeric field.
That said, in certain context, VBA functions reserve a space in string representations of numbers for the sign. A nonsensical example of this would be:
?Len("12345")
5
Notice the space at the beginning (where the - would be if the number returned by Len() could be negative). I thought this was a result of coercing a number to a string value, but that's not it, and I couldn't replicate the problem. But that would likely be the source of the problem, and, of course, trimming off the leading space would take care of the issue.
But that's two function calls for each line, and then you're sorting by it, and that means no use of indexes, so it's going to be slow relative to a SORT BY that can use indexes. So, I'd conclude you have a schema error, in that you're giving meaning to a subpart of the data stored in the field.
It seems pretty obvious that you have a blank space at the end of the Sector field that the trim is removing.
I don´t have a field as such, but I am making a new field which is the result dividing an existing field, i.e. cost/1.15
Is there a way to restrict the result of this calculation to two decimal places?
You could change the column type to a NUMERIC(p, 2) where p is the precision, especially if it is money (I'm guessing from cost that it might be money).
Also making a column which is derived from another column is generally a bad idea as the two can get out of sync. Consider making a view instead.
Sounds like you need the ROUND() function.
Eg. ROUND(cost/1.15, 2)