SQL query erroring - need fresh eyes - sql

Ok, first, I'm building a query to search MLS data that has been provided in the form of a MySQL database, So I don't have control over the data format, and thus I believe I have to do a lot of casting to get the data in a manageable form. The SQL error is being thown.
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near ' DECIMAL(2, 1)) / .5,
CAST(idx1.full_baths, DECIMAL(2, 1))), DECIMAL(2, 1)) AS b' at line 1
Looked up the error code and it sends me to a reserved words page, but I can't identify any reserved words.
and now the sql
(all fields are natively VARCHAR)
SELECT idx_common.mls_no AS mls_no,
CONCAT_WS(" ", idx_common.street_no, idx_common.street_direction, idx_common.street_name) AS address,
idx_common.city AS city,
idx_common.state AS state,
idx_common.total_sqft AS total_sqft,
idx_common.asking_price AS price,
idx1.bedrooms AS bedrooms,
CAST(
SUM(
(CAST(idx1.half_baths, DECIMAL(2, 1)) / .5),
CAST(idx1.full_bath, DECIMAL(2, 1))
),
DECIMAL(2, 1)
) AS bathrooms,
idx1.residential_prop_type AS type,
"Listing Agent" AS agent
FROM (idx_common)
JOIN idx1 ON idx_common.mls_no = idx1.mls_no
WHERE `idx_common`.`mls_no` = 'query'
OR idx_common.zip LIKE '%query%'
OR idx_common.city LIKE '%query%'

I believe you don't need SUM here at all:
SELECT idx_common.mls_no AS mls_no,
CONCAT_WS(" ", idx_common.street_no, idx_common.street_direction, idx_common.street_name) AS address,
idx_common.city AS city,
idx_common.state AS state,
idx_common.total_sqft AS total_sqft,
idx_common.asking_price AS price,
idx1.bedrooms AS bedrooms,
CAST(idx1.half_baths AS DECIMAL(2, 1)) * .5 +
CAST(idx1.full_bath AS DECIMAL(2, 1)) AS bathrooms,
idx1.residential_prop_type AS type,
"Listing Agent" AS agent
FROM idx_common
JOIN idx1
ON idx_common.mls_no = idx1.mls_no
WHERE `idx_common`.`mls_no` = 'query'
OR idx_common.zip LIKE '%query%'
OR idx_common.city LIKE '%query%'
I also changed / 0.5 to * 0.5 since it seems to be more appropriate for this query.
If an apartment has 3 half bathrooms and 2 full bathrooms, this query will output (3 / 2) + 2 = 3.5 bathrooms.
Is it what you wanted?

SUM() takes a single argument. You have SUM( Cast(...), Cast(...) )
I think you meant to do +, not SUM
(CAST(idx1.half_baths, DECIMAL(2, 1)) / .5) +
CAST(idx1.full_bath, DECIMAL(2, 1))
SUM adds all values of the column in the whole table. You can only use it in a GROUP BY query.

I believe that the function CAST works with AS, not a ",". Like this:
CAST(idx1.half_baths AS DECIMAL(2, 1))
You need to replace that on all your CASTs.

Ensure that your MYSQL version is > 5.0.8. The DECIMAL type wasn't added to the CAST function until this version.

Related

Add string to end of IsNull expression

I'd like to add a divisor symbol (%) to the end of my expression shown here:
select 'On-Site Case Rate' Exp1,
isnull(sum(onsite.a) * 100 / count(onsite.casecount), 0) '400',
isnull(sum(onsite.b) * 100 / count(onsite.casecount), 0) '401'
from onsite
How would I go about doing that? Do I need to use a concat and reformat my query or is it possible to insert a " + '%' "+ somewhere?
Here is a sample result, this is for an SSRS report
EDIT1: Here is the design view of my report as well
Considering that you're using SSRS, don't try to add a % sign to the end of your percentage, and convert it to a varchar, leave it as a decimal. Instead, change your display format.
Select the cell(s) that are returning your percentages and press F4. Then, in the now targeted Properties Pane locate the Format Property and change it to 0%. If you want it to display 1 (or more) decimal places then use 0.0%, 0.00%, ... you get the idea.
Note that you need to ensure that your values are returning a decimal value. You're multiplying your values by 100, which implies that you aren't. 15 isn't 15%, it's 1500%. 15% = 0.15.
In Sql Server (starting with version 2012) you can use the CONCAT function:
select 'On-Site Case Rate' Exp1,
CONCAT(isnull(sum(onsite.a) * 100 / count(onsite.casecount), 0), '%') '400',
CONCAT(isnull(sum(onsite.b) * 100 / count(onsite.casecount), 0), '%') '401'
from onsite

SQL: Cannot convert nvarchar to numeric in complex query

I need to get the nearest airport in my database table from the current users position. I found this formula: https://de.scribd.com/presentation/2569355/Geo-Distance-Search-with-MySQL#page=7
So there are a few differences between the formula described in the link above and my current situation: The example was in MySQL, I'm using MS SQL (not a problem, I guess). lat and lon are considered to be database columns with numeric data type, but for some reason the database table was created with two corresponding columns of type varchar.
My problem is: When I want to use an ORDER BY clause, it throws Error converting data type nvarchar to numeric, without it, it works. I did some research on what rubbish was inserted as string and migrated it so that I just have some empty values.
I can't take all because I only need one. But if I do TOP 1 without ORDER BY I don't get any airport rather than the nearest airport. Does anyone know how to fix the query?
Thanks in advance!
SELECT TOP 1
temp.Distance
FROM (
SELECT
(
3956 * 2 * ASIN(
SQRT(
POWER(
SIN((53.6349994 - abs(CAST(latitude_deg AS numeric))) * pi() / 180 / 2), 2) + COS(53.6349994 * pi()/180) * COS(abs(CAST(latitude_deg AS numeric)) * pi()/180) * POWER(SIN((10.0117336 - CAST(longitude_deg AS numeric)) * pi()/180 / 2), 2) ))) AS Distance
FROM Airport_Airports
WHERE
isnumeric(longitude_deg) = 1 AND isnumeric(latitude_deg) = 1 AND
longitude_deg LIKE '%[^0-9.]%' AND latitude_deg LIKE '%[^0-9.]%'
) AS temp
WHERE
temp.Distance < 50000
Order BY
temp.Distance
First, this logic doesn't make sense:
WHERE isnumeric(longitude_deg) = 1 AND
isnumeric(latitude_deg) = 1 AND
longitude_deg LIKE '%[^0-9.]%' AND
latitude_deg LIKE '%[^0-9.]%'
The like is looking for non-numeric characters. I think you intend:
WHERE isnumeric(longitude_deg) = 1 AND
isnumeric(latitude_deg) = 1 AND
longitude_deg NOT LIKE '%[^0-9.]%' AND
latitude_deg NOT LIKE '%[^0-9.]%'
This ensures that the values are numeric.
The solution to your problem -- at least in SQL Server 2012+ -- is to use try_convert() or try_cast():
(3956 * 2 * ASIN(
SQRT(
POWER(
SIN((53.6349994 - abs(try_convert(numeric, latitude_deg))) * pi() / 180 / 2), 2) + COS(53.6349994 * pi()/180) * COS(abs(try_convert(numeric, latitude_deg)) * pi()/180) * POWER(SIN((10.0117336 - try_convert(numeric, longitude_deg)) * pi()/180 / 2), 2) ))) AS Distance
This will prevent any conversion errors.
You shouldn't use just numeric. Use either a floating point representation or something with decimal places, say numeric(20, 10).
The reason this occurs with the order by is because of the SQL optimizer. You clearly have some lat/long values that do not convert correctly to a numeric. SQL Server allows itself to re-arrange operations, so the conversion might take place before the filtering by the where clause. This is part of the overall query optimization.

SQL Server - Delete Values after Decimal (non-int field)

Have a ncarchar(MAX) field in SQL table. It has numbers such as 717.08064182582, 39.0676048113, etc. in which I need to only have 3 places after decimal. For instance 717.080, 39.067.
Without converting the field type, would like to get rid of those last n characters, however every row has different number of characters. I believe I could use ROUND (correct me if wrong), but would rather not.
Try this
SELECT CAST(ColumnName AS DECIMAL(18,3))
Without converting it data type As per #vkp Comment
SELECT SUBSTRING(ColumnName ,0,CHARINDEX('.', ColumnName )+4)
select CASE WHEN CHARINDEX('.', Your_column) > 0
THEN SUBSTRING(Your_column, 1, CHARINDEX('.', Your_column) + 3)
ELSE Your_column
END
this is similar as previous answers but more faster and safer
Try this:
SELECT SUBSTRING(Your_column, 1, PATINDEX('%.%', Your_column) + 3)
FROM Your_Table

Remove trailing zero from decimal number

I have a one database table field called Amount which type is decimal(18,6). so it is stored in database up to 6 decimal points like 9.786534 But while retrieving that field using select query i have to take care like following
Remove trialling zero e.g if number is 9.230000 then result is only 9.23
If decimal points are all zero then only remove only four trialling zero e.g If number is 9.000000 then result is 9.00
Result is up to 2 decimal point if there are trialling zero.
If we write simple query like
select TOP 1 Amount From EmployeeMaster
then it gives 9.230000
but my intension is to remove trailing zero..
Please help me..
It works for removing trailing zeros, but I am still not able to convert 9 to 9.00 in this method.
Declare #myvalue varchar(50),
#Price Varchar(50)
Set #Price = '9.230000'
set #Myvalue = reverse(substring(#Price,patindex('%.%',#Price)+1,len(#Price)))
SELECT
case
When patindex('%.%[1-9]%',#price) = 0 Then
substring(#price,1,patindex('%.%',#price)-1)
else
substring(#price,1,patindex('%.%',#price)-1) + '.' + Reverse(substring(#Myvalue,patindex('%[1-9]%',#Myvalue),len(#Myvalue)))
END
Coming from decimal(18,6) you could do...
select cast(Amount as decimal(18,2))
Most databases that support the CAST function will round the number while converting it. On SQLServer this is what I would do if I wanted rounding.
If what you actually want is a string with only two digits after the decimal then you could
select cast((Amount as decimal(18,2)) as nvarchar)
nvarchar is SQLServer's variable length unicode type. Databases do not agree much on string types. Your database may have a different one. The rest of that sql is ANSI standard. Not all dbs support that either but many do.
This should work
SELECT CAST(REPLACE(RTRIM(REPLACE(CAST(CAST(33.9082976 AS DECIMAL(38,8)) AS NVARCHAR(256)),'0',' ')),' ','0') AS FLOAT)
Does this work?
select TOP 1 ROUND(Amount, 2) From EmployeeMaster
TRY below mentioned code.
SELECT TOP 1 CONVERT(DECIMAL(10,2),Amount) From EmployeeMaster
Hope it will work as expected.
An alternative approach:
1) convert the decimal to a string;
2) split the string into 2 parts, separating the last 4 characters from the rest of the string;
3) remove trailing zeros from the last 4 characters;
4) concatenate the two parts back.
WITH data (V) AS (SELECT CAST(9.786534 AS decimal(18,6))
UNION ALL
SELECT CAST(9.78653 AS decimal(18,6))
UNION ALL
SELECT CAST(9.7800 AS decimal(18,6))
UNION ALL
SELECT CAST(9.7 AS decimal(18,6))
UNION ALL
SELECT CAST(9.00000 AS decimal(18,6))
)
, AsString (V) AS (SELECT CAST(V AS varchar) FROM data)
, Split (L, R) AS (SELECT LEFT(V, LEN(V) - 4), RIGHT(V, 4) FROM AsString)
, Adjusted AS (SELECT L,
REPLACE(RTRIM(REPLACE(R, '0', ' ')), ' ', '0') AS R
FROM Split)
SELECT Result = L + R FROM Adjusted
The output of the above script is:
Result
--------
9.786534
9.78653
9.78
9.70
9.00
I guess using patindex in your case:
CASE WHEN FLOOR(Amount) <> CEILING(Amount) THEN
LTRIM(SUBSTRING(STR(Amount, 18, 6), 1, LEN(STR(Amount, 18, 6)) - PATINDEX('%[^0]%', REVERSE(str(Amount, 18, 6))) + 1))
ELSE STR(Amount,18,2)
END
for a decimal(18,6) field this should work:
select trim(to_char(Amount, '999999999999999999.99')) from EmployeeMaster
(at least for Oracle, not sure about other types)

SQL - How do i output string with numbers in sql?

I want to get a number 5000.1 and divide it by 1000 before adding an "F" infront of it.
How do i do this? I tried and failed this:
select "F" + round ( acq.store_size_net / 1000, 0) from acq
I suspect your missing the cast of the number to a text data type
Without knowing the exact dialect of sql you're using im gonna hazard a guess at ms-sql
select 'F' + cast(cast(round ( 5000.1 / 1000, 0)as int) as nvarchar(50))
produces output
F5
This will work in Oracle :
select 'F' || round (acq.store_size_net / 1000, 0) from acq