Can someone tell me what's wrong with my code?
sinlaw('?',150,30,39.8)
parse error near line 30 of file
'endfunction' command matched by 'endif'
function [phi] = sinlaw (A,a,B,b)
If A==('?')
a=deg2rad(a)
b=deg2rad(b)
A=(B/sin(b))*sin(a)
endif
if(a=='?')
a=deg2rad(asin((A/B)*sin(b)))
endif
endfunction
While the syntax-check whines about matched by endif
The problem is actually in the If... typo
Feel free to test it here.
function [phi] = sinlaw ( A, a, B, b )
if A == ( '?' ) %% this works, not the "If"
a = deg2rad( a )
b = deg2rad( b )
A = ( B / sin( b ) ) * sin( a )
endif
if ( a == '?' )
a = deg2rad( asin( ( A / B ) * sin( b ) ) )
endif
endfunction
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sinlaw( 150, '?', 30, 39.8 )
sinlaw( '?', 150, 30, 39.8 )
Related
I tried finding the answer, but maybe I am too new to MSSQL, I come from MySQL, so this is my question super simplified to go straight to the point:
Imagine we have a table "Things"
Thingie | Value
--------+-------
Thing1 | 10
Thing1 | 15
Thing1 | 16
In MySQL I could do something like this in a query:
SET #halfvalue := 0;
SELECT Thingie, Value,
(#halfvalue := Value / 2) AS HalfValue,
(#halfvalue / 2) AS HalfOfHalf
FROM Things
Which would return
Thingie | Value | HalfValue | HalfofHalf
--------+-------+-----------+------------
Thing1 | 10 | 5.00 | 2.50
Thing1 | 15 | 7.50 | 3.75
Thing1 | 16 | 8.00 | 4.00
Looks pretty simple, the actual one is a tad more complicated.
My problem is, in MSSQL I can't assign, and use a variable on the same SELECT. And I can't find anything similar to this functionality on this simple level.
Any solutions?
Edit, this is the select that contains all those nasty operations:
SELECT
fvh.DocEntry,
MAX( fvs.SeriesName ) AS "Serie",
MAX( fvh.DocNum - 1000000 ) AS "Número",
MAX( fvh.DocDate ) AS "Fecha",
MAX( fvh.U_FacNit ) AS "NIT",
MAX( fvh.U_FacNom ) AS "Nombre",
MAX( IIF( ISNULL( fvh.Address, '' ) = '', fvh.Address2, fvh.Address ) ) AS "Dirección",
SUM( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) AS "Total",
IIF( MAX( fvh.CANCELED ) = 'Y' OR ( SUM( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) = 0 ),
'Anulada',
IIF( SUM( fvd.GTotal ) > SUM( ISNULL( ncd.GTotal, 0 ) ) AND ( SUM( ISNULL( ncd.GTotal, 0 ) ) > 0 ),
'Devuelta',
'Emitida' )
) AS "Estado",
ROUND( ( ( SUM( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ), 4 ) AS "IVA",
ROUND( SUM( IIF( fvd.U_TipoA = 'BB',
( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) - ( ( ( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ),
0 ) ), 4) AS "Bien",
ROUND( SUM( IIF( fvd.U_TipoA = 'S',
( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) - ( ( ( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ),
0 ) ), 4) AS "Servicio",
ROUND( SUM( IIF( fvd.U_TipoA = 'N',
( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) - ( ( ( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ),
0 ) ), 4) AS "No Aplica",
COUNT(fvd.LineNum) AS "Lineas", SUM(fvd.GTotal) AS "FCTotal",
SUM(ISNULL( ncd.GTotal, 0 )) AS "NCTotal"
/* Facturas */
FROM OINV AS fvh
LEFT JOIN NNM1 AS fvs ON fvs.Series = fvh.Series
LEFT JOIN INV1 as fvd ON fvd.DocEntry = fvh.DocEntry
/* Notas de Credito */
LEFT JOIN RIN1 AS ncd ON ncd.BaseEntry = fvh.DocEntry AND ncd.LineNum = fvd.LineNum
WHERE fvh.DocDate BETWEEN ? AND ? /*AND fvh.DocEntry = 1108*/
GROUP BY fvh.DocEntry
Thank you all for your time. I will dismantle my query and re-do it taking into consideration all of your input. Gracias, totales.
You think you can do this in MySQL:
SET #halfvalue := 0;
SELECT Thingie, Value,
(#halfvalue := Value / 2) AS HalfValue,
(#halfvalue / 2) AS HalfOfHalf
FROM Things;
But you are wrong. Why? MySQL -- as with every other database -- does not guarantee the order of evaluation of expression in a SELECT. The documentation even warns about this:
In the following statement, you might think that MySQL will evaluate #a first and then do an assignment second:
SELECT #a, #a:=#a+1, ...;
However, the order of evaluation for expressions involving user variables is undefined.
In both databases, you can use a subquery. In the most recent versions of MySQL (and just about any other database), you can also use a CTE:
SELECT Thingie, Value, HalfValue,
(HalfValue / 2) AS HalfOfHalf
FROM (SELECT t.*, (Value / 2) AS HalfValue
FROM Things t
) t;
The answer is simple: you can't do that in MSSQL, because when you try it you'll get:
Msg 141, Level 15, State 1, Line 3
A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations.
which you most probably experienced.
The most simple workaround would be:
SELECT Thingie, Value, Value/2, Value/4 from Things
Other method:
select Thingie, Value, HalfValue, HalfValue / 2 from (
SELECT Thingie, Value, Value / 2 HalfValue from Things
) a
No, that doesn't work in SQL. The parameter value is not set until the query completes. You can do it in two steps:
DECLARE #halfvalue FLOAT = 0;
SELECT #halfvalue = ([Value] / 2)
FROM Things ;
SELECT Thingie
, [Value]
, HalfValue = [Value]/2
, HalfAgainValue = #halfvalue / 2
FROM Things ;
I would need your help to fix a problem I'm facing.. I'm using a CASE function and aliasing its result by adding "AS 'RESULT'" after its "END".
Event though the query seems to run, I'm still getting the following warnings through phpmyadmin :
Unrecognized keyword (near AS)
Unexpected token (near 'RESULT')
I have no idea on why I'm getting this...I would appreciate your help to highlight my mistake ;-)
SELECT
app_fd_List_of_components.c_component,
app_fd_List_of_orders.c_package,
app_fd_List_of_orders.c_status,
app_fd_List_of_orders.dateCreated,
app_fd_List_of_orders.c_orderId,
app_fd_List_of_orders.Id,
temptablename.datetime AS Int_Date,
temptablename2.datetime AS Prdw3_Date,
#counterStatus := IF(
app_fd_List_of_orders.c_status <> 'Deployment completed',
IF(
temptablename.datetime IS NOT NULL,
'Counting',
'Initializing'
),
'Complete'
) AS 'Counter_status',
#counter := IF(
app_fd_List_of_orders.c_status <> 'Deployment completed',
IF(
temptablename.datetime IS NOT NULL,
(
35 - DATEDIFF(
CURRENT_DATE(), temptablename.datetime)
),
'n/a'
),
DATEDIFF(
temptablename2.datetime,
temptablename.datetime
)
) AS 'Counter',
CASE (WHEN(
(#counterStatus = 'Counting') AND(#counter < 0)
) THEN "black" WHEN(
(#counterStatus = 'Counting') AND(#counter > 5)
) THEN "green" WHEN(
(#counterStatus = 'Counting') AND(-1 < #counter < 5)
) THEN "orange" WHEN(
(#counterStatus = 'Complete') AND(#counter > 35)
) THEN "black" WHEN(
(#counterStatus = 'Complete') AND(#counter < 35)
) THEN "green" ELSE "n/a")
END AS 'RESULT'
FROM
app_fd_List_of_orders
JOIN app_fd_List_of_components ON
app_fd_List_of_orders.c_component = app_fd_list_of_components.id
LEFT JOIN(
SELECT app_form_data_audit_trail.datetime,
app_form_data_audit_trail.data
FROM
app_form_data_audit_trail
WHERE
SUBSTRING_INDEX(
SUBSTRING_INDEX(
app_form_data_audit_trail.data,
'"opdetails":"',
-1
),
'"',
1
) = 'int'
) AS temptablename
ON
app_fd_list_of_orders.c_orderid = SUBSTRING_INDEX(
SUBSTRING_INDEX(
temptablename.data,
'"orderId":"',
-1
),
'"',
1
)
LEFT JOIN(
SELECT app_form_data_audit_trail.datetime,
app_form_data_audit_trail.data
FROM
app_form_data_audit_trail
WHERE
SUBSTRING_INDEX(
SUBSTRING_INDEX(
app_form_data_audit_trail.data,
'"opdetails":"',
-1
),
'"',
1
) = 'prdw3'
) AS temptablename2
ON
app_fd_list_of_orders.c_orderid = SUBSTRING_INDEX(
SUBSTRING_INDEX(
temptablename2.data,
'"orderId":"',
-1
),
'"',
1
)
Have you tried removing the parentheses around the CASE statement?
CASE
WHEN #counterStatus = 'Counting' AND #counter < 0 THEN "black"
WHEN #counterStatus = 'Counting' AND #counter > 5 THEN "green"
WHEN #counterStatus = 'Counting' AND -1 < #counter < 5 THEN "orange"
WHEN #counterStatus = 'Complete' AND #counter > 35 THEN "black"
WHEN #counterStatus = 'Complete' AND #counter < 35 THEN "green"
ELSE "n/a"
END AS 'RESULT'
EDIT: I'm also not sure this is possible:
WHEN #counterStatus = 'Counting' AND -1 < #counter < 5 THEN "orange"
It may need to be written as:
WHEN #counterStatus = 'Counting' AND -1 < #counter AND #counter < 5 THEN "orange"
I am implementing a search filter in my web app. using sub-queries like this:
tool = Tool.select('*, (select ROUND(AVG(ratings.rating)) from ratings where tool_id = tools.id AND rating_type = 2) as ratings,
3956 * 2 * ASIN(SQRT(POWER(SIN(('+"#{params[:latitude]}"+' - abs(tools.latitude)) * pi()/180 / 2), 2) + COS('+"#{params[:latitude]}"+' * pi()/180 ) * COS(abs(tools.latitude) * pi()/180) * POWER(SIN(('+"#{params[:longtude]}"+' - abs(tools.longitude)) * pi()/180 / 2), 2) )) as distance').where('user_id != ? AND pause_status =?', user_id, 0).order('distance asc')
# =>delivery type only if delivery type is 1
if params[:search].present? && !params[:search].nil?
tool = tool.where('title LIKE ? OR description LIKE ?', "%#{params[:search]}%","%#{params[:search]}%")
end
# =>Category search
if params[:category_id].present? && !params[:category_id].nil?
tool = tool.where('category_id =?', params[:category_id])
end
# =>price range
if params[:max_price].present? && params[:min_price].present? && !params[:max_price].nil? && !params[:min_price].nil?
tool = tool.where('price >= ? AND price <= ?', params[:min_price].to_f, params[:max_price].to_f)
end
# => filter availability
if params[:availability].present? && !params[:availability].nil?
if params[:availability].to_i == 2
tool = tool.where('available_type =?', 2) #=> weekend
elsif params[:availability].to_i == 1
tool = tool.where('available_type =?', 1) # => weekdays
end
end
if params[:rating].present? && !params[:rating].nil?
tool = tool.having('ratings > 5')
end
if params[:delivery_type].present? && !params[:delivery_type].nil?
if params[:delivery_type].to_i == 0
tool = tool.where('delivery_type = ?', 0)
end
end
if tool.empty?
return []
else
tool_array = []
tool.each do |t|
tool_hash = {}
tool_hash['id'] = t.id
tool_hash['title'] = t.title
tool_hash['latitude'] = t.latitude
tool_hash['longitude'] = t.longitude
tool_hash['attachment'] = Image.get_single_attachment(t.id)
tool_array.push(tool_hash)
end
return tool_array
end
when I pass rating parameter it print the query like this:
SELECT COUNT(*) FROM `tools` WHERE (user_id != 3 AND pause_status =0) HAVING (ratings > 5)"
and without rating parameter:
SELECT *, (select ROUND(AVG(ratings.rating)) from ratings where tool_id = tools.id AND rating_type = 2) as ratings, 3956 * 2 * ASIN(SQRT(POWER(SIN((30.657797735213 - abs(tools.latitude)) * pi()/180 / 2), 2) + COS(30.657797735213 * pi()/180 ) * COS(abs(tools.latitude) * pi()/180) * POWER(SIN((76.7327738833397 - abs(tools.longitude)) * pi()/180 / 2), 2) )) as distance FROM `tools` WHERE (user_id != 3 AND pause_status =0) ORDER BY distance asc"
and I a error like this in my having clause:
"error": "Mysql2::Error: Unknown column 'ratings' in 'having clause': SELECT COUNT(*) FROM `tools` WHERE (user_id != 3 AND pause_status =0) HAVING (ratings > 5)",
"code": 301
and if I comment the each loop it works.
Please tell where I am doing wrong.
having should work with group by
You can't use alias name as ratings in the following line,
select ROUND(AVG(ratings.rating)) from ratings where tool_id = tools.id AND rating_type = 2) as ratings
Give a different name as MYSQL confusing ratings as column.
I am trying to get rows from a table where there are matches on multiple other tables.
This is the query I am running.
SELECT qt.*, DATEDIFF(CURRENT_DATE, STR_TO_DATE(up.DOB, '%m-%d-%Y')) / 365 AS Age
FROM UserProfile AS up, Game AS g, QuestionTable AS qt
WHERE NOT EXISTS(SELECT * FROM Options WHERE UserID = 75 AND QID = qt.QID AND DateTime >= CURDATE())
AND g.Active = 1 AND g.QID = qt.QID
AND (((g.Gender = up.Gender OR g.Gender = 'B') AND ((g.City = up.City AND g.Zip = up.Zip AND g.Country = up.Country) OR g.Home = 0) AND ((Age BETWEEN g.Maximum AND g.Minimum) OR g.Age = 0) AND ((SQRT( POW( 69.1 * ( g.Latitude - -93.5746359 ) , 2 ) + POW( 69.1 * ( 44.9737707 - g.Longitude ) * COS( g.Latitude / 57.3 ) , 2 ) ) > g.Distance) OR g.Geo = 0)) OR g.Special = 0)
GROUP BY qt.QID
I have ran this expression through C# and it returns true, yet it is only matching on the 'g.Special = 0' part through MySql.
Any help on this would be much appreciated!
Resolved the issue by fixing some mistakes I made and changed the query to this,
SELECT *
FROM QuestionTable AS qt
WHERE NOT EXISTS
(SELECT * FROM Options WHERE UserID = 75 AND QID = qt.QID AND DateTime >= CURDATE())
AND EXISTS(SELECT g.* FROM UserProfile AS up, Game AS g WHERE g.Active = 1 AND g.QID = qt.QID AND(g.Special = 0 OR(
(g.Gender = up.Gender OR g.Gender = 'B') AND
((g.City = up.City AND g.zip = up.Zip AND g.Country = up.Country) OR g.Home = 0) AND
((SQRT( POW( 69.1 * ( g.Latitude - 44.9737707 ) , 2 ) + POW( 69.1 * ( -93.5746359 - g.Longitude ) * COS( g.Latitude / 57.3 ) , 2 ) ) < g.Distance) OR g.Geo = 0) AND
((DATEDIFF(CURRENT_DATE, STR_TO_DATE(DOB, '%m/%d/%Y'))/365.25 BETWEEN g.Minimum AND g.Maximum) OR g.Age = 0))))
I can't for the life of me spot my typo!
UPDATE orders o, orders_total_couponz otc
SET o.total_paid = o.total_paid - ( otc.converted_value * ( 1 + ( otc.tax_rate / 100 ) ) ),
SET o.total_paid_tax_incl = o.total_paid_tax_incl - ( otc.converted_value * ( 1 + ( otc.tax_rate / 100 ) ) ),
SET o.total_paid_tax_excl = o.total_paid_tax_excl - otc.converted_value,
SET o.total_paid_tax_real = o.total_paid_tax_real - ( otc.converted_value * ( 1 + ( otc.tax_rate / 100 ) ) ),
SET o.total_products = o.total_products - otc.converted_value,
SET o.total_products_wt = o.total_products_wt - ( otc.converted_value * ( 1 + ( otc.tax_rate / 100 ) ) )
WHERE o.id_order = otc.orders_id
error:
#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 'SET o.total_paid_tax_incl = o.total_paid_tax_incl - ( otc.converted_value * ( 1 ' at line 3
Use the set keyword only once, and comma-separate the values to set:
UPDATE orders o, orders_total_couponz otc
SET o.total_paid = o.total_paid - ( otc.converted_value * ( 1 + ( otc.tax_rate / 100 ) ) ),
o.total_paid_tax_incl = o.total_paid_tax_incl - ( otc.converted_value * ( 1 + ( otc.tax_rate / 100 ) ) ),
o.total_paid_tax_excl = o.total_paid_tax_excl - otc.converted_value,
o.total_paid_tax_real = o.total_paid_tax_real - ( otc.converted_value * ( 1 + ( otc.tax_rate / 100 ) ) ),
o.total_products = o.total_products - otc.converted_value,
o.total_products_wt = o.total_products_wt - ( otc.converted_value * ( 1 + ( otc.tax_rate / 100 ) ) )
WHERE o.id_order = otc.orders_id
Do not use SET again and again. Use command like:
UPDATE orders o, orders_total_couponz otc
SET o.total_paid = o.total_paid - ( otc.converted_value * ( 1 + ( otc.tax_rate / 100 ) ) ),
o.total_paid_tax_incl = o.total_paid_tax_incl - ( otc.converted_value * ( 1 + ( otc.tax_rate / 100 ) ) ),
o.total_paid_tax_excl = o.total_paid_tax_excl - otc.converted_value,
o.total_paid_tax_real = o.total_paid_tax_real - ( otc.converted_value * ( 1 + ( otc.tax_rate / 100 ) ) ),
o.total_products = o.total_products - otc.converted_value,
o.total_products_wt = o.total_products_wt - ( otc.converted_value * ( 1 + ( otc.tax_rate / 100 ) ) )
WHERE o.id_order = otc.orders_id