What could be wrong with this select statement? I get an error called incorrect syntax near 'A'.
Since I am more used to write queries in postgreSQL, my guess is that MySQL has a bit different syntax.
cmd.CommandText = "WITH CurrentStop AS (SELECT[Stop Id] FROM Stops WHERE[Route Id] = " +
routeId + "AND Serial = " + stopsDriven + ")" +
"SELECT A.Firstname, A.Lastname, B.Make, B.Capacity, B.Route, D.Name" +
"FROM Driver A, Bus B, CurrentStop C, Stop D" +
"WHERE A.Id = " + row[0] + "AND B.[Bus Id] = " + row[1] + "AND C.[Stop Id] = D.[Stop Id]";
By the way, all inputs are in system only so no SQL injection could possibly happen.
Print out the query before trying to execute it and examine it closely. This solves a large chunk of the "what's wrong with my dynamically generated query?" style questions we see here.
For example, I'd be wary of the lack of space between (not necessarily an exhaustive list, these are just the ones I noticed):
routeId and the following AND;
row[0] and the following AND;
row[1] and the following AND;
D.Name and the following FROM; and
Stop D and the following WHERE.
Those last two are definitely problematic since, while it is possible the variables may end in a space (though unusual), the fixed strings certainly don't. And both may be causing the specific error you see since they would come out as:
D.NameFROM Driver A
Stop DWHERE A.
Related
I have a data table that looks like the below. This shows the top 3 subcallcategories based on the amount of calls. The "order" column is a row number that shows which order the subcallcategory was in based on the calls.
I am trying to write some DAX in SSRS which displays the following
Anxiety was the most common counselling call, followed by Work Related
Stress and Bereavement
I have written the below code however it doesn't seem to be picking up the last 2 categories? Anyone have any ideas what I am doing wrong?
=IIf(Fields!Order.Value = "1" and Fields!Category.Value = "Counselling", Fields!SubCallCategory.Value, "") &
" was the most common counselling call, followed by " &
IIf(Fields!Order.Value = "2" and Fields!Category.Value = "Counselling", Fields!SubCallCategory.Value, "") &
" and " & IIf(Fields!Order.Value = "3" and Fields!Category.Value = "Counselling", Fields!SubCallCategory.Value, "")
Below is my current output
As Alan mentioned, your expression is just looking at a single row of data.
You would need to put this expression in a table with Grouping by Category.
Then you would look for the ones in your ORDER and use that Sub Cat value. I use MAX and NULL to get matching values like
=MAX(IIf(Fields!Order.Value = 1, Fields!SubCallCategory.Value, NOTHING)) &
" was the most common " & Fields!Category.Value & " call, followed by " &
MAX(IIf(Fields!Order.Value = 2, Fields!SubCallCategory.Value, NOTHING)) &
" and " & MAX(IIf(Fields!Order.Value = 3, Fields!SubCallCategory.Value, NOTHING))
The MAX will get the SubCat value over NOTHING (SSRS for NULL) for the ones in the right ORDER.
This would give one line for Counselling and one for Legal.
You could also add the totals in with
MAX(IIf(Fields!Order.Value = 1, Fields!Calls.Value, 0))
I assume your ORDER field is an INTEGER and doesn't need the quotes.
Generally people use the default option that Spotfire gives. Connect to the DB and pull the set of columns that you need and create an Information Link and load the data to Spotfire.
However, I am using SQL Query to fetch data to Spotfire. I am creating a table similar to Views, and writing a simple stored procedure to pull the data:
Create procedure ProcA(In Start_Date date, IN End_Date date, In Site_Name text)
Begin
SELECT * FROM TableA where day between Start_Date and End_Date and
site_name = Site_Name;
This works fine if I am not using site name filtering.
The Information Links helps in filtering the date properly. But when it comes to Site Name, nothing works.
There are 2 requirements:
Is it possible to give a drop-down just like how filter comes for Date
How to pass multiple site names to pull only those sites into the Spotfire file
TL;DR: There are better ways to do this; if it's just for the column names, I don't think it's worth it to do part 2, since it's easy enough to change the sql in the information link, but it's possible.
Okay, I will try (read: fail) not to be too long-winded.
1) Is it possible to do a drop-down for dates? Yes. The easiest way to do this would be to pull a data table with all of your date choices available for the end user. Here's an example finding a list of better way to generate months/year table Remember when creating your dropdownlist that your Document Property has to have the Data type "Date", and then you should be able to set property values through Unique Values in column against your date column from the new data, the same as you would do for a string drop-down list.
If you have a small subset of specific dates to choose from, this probably isn't too bad. If the drop down list gets longer, your end-users can type in the date they're looking for to speed up their search (though in my experience, a lot of them will scroll through until they find the date they're looking for).
While this is perfectly acceptable, if you're at all comfortable adding javascript, I'd personally recommend using a Popup Calendar These are fairly straightforward for end-users, and can allow them to use the calendar or type it themselves. (And if they type something that isn't a date in, it's even kind enough to inform them with red letters and an exclamation mark that they haven't typed an actual date)
2) How to pass multiple site names to pull only those sites into the Spotfire file
Hoo boi, where to start.
Step one: How do you want to select your list of Site Names? I'm going to go ahead and assume you have a data table with a list of distinct Site Names.
Your next choice is how to let your user select which Site Names they want. General options are using a List Box Filter, displaying a table and using marked rows, or providing a text area where the user can type their selections themselves.
When I needed to do this, I did a combo of a data table and a text area, so that's what I'm going to describe here.
I start off by providing the user with a text area, formatted to "specific size" with a larger than usual height to prompt that, yes, they are allowed to type multiple rows. If they know the values they're looking for, they can type them in manually, or copy paste from an excel file, etc.
If they don't know what they're looking for, the list of Site Names would be in a Table displayed for the user, where they can then mark the rows they want on the visualization and push a button which will do a cursor through the list of marked Site Names, concatenate them together, and put them in the text box previously mentioned (Note: if you don't want to let them enter their list manually, you can leave off the text area, combine these next two pieces of code, and throw it straight into the SpecialFilterProperty).
Please note that cursors are slow; if you have more than a few thousand rows to cycle through, this may stall out for a few seconds.
Code for the button:
from Spotfire.Dxp.Application.Visuals import CrossTablePlot
from Spotfire.Dxp.Data import IndexSet
from Spotfire.Dxp.Data import RowSelection
from Spotfire.Dxp.Data import DataValueCursor
from Spotfire.Dxp.Data import DataSelection
TextFltr = ""
crossSource = Document.Data.Tables["Distinct_SiteNames"]
##Get a Row Count
rowCount = Document.Data.Tables["Distinct_SiteNames"].RowCount
##Index Set of all our rows
rowIndexSet=Document.ActiveMarkingSelectionReference.GetSelection(Document.Data.Tables["Distinct_SiteNames"]).AsIndexSet()
allRows = IndexSet(rowCount,True)
if rowIndexSet.IsEmpty != True:
allRows = rowIndexSet
colCurs = DataValueCursor.CreateFormatted(crossSource.Columns["Site_Name"])
##Optional: Loop through to determine average value
colTotal = ''
for row in crossSource.GetRows(allRows, colCurs):
colTotal += ', ' + colCurs.CurrentValue
if TextFltr == "":
TextFltr += colTotal[2:]
else:
TextFltr += colTotal
Document.Properties["SelectedSiteNames"] = TextFltr
from System.Collections.Generic import Dictionary
from Spotfire.Dxp.Application.Scripting import ScriptDefinition
import clr
scriptDef = clr.Reference[ScriptDefinition]()
Document.ScriptManager.TryGetScript("Change Special Filter Value", scriptDef)
params = Dictionary[str, object]()
Document.ScriptManager.ExecuteScript(scriptDef.ScriptCode, params)
At the bottom it references a second script; this is the script attached to the button that parses through the text area when the user wants to submit their selections and refresh the data table.
The General Code I've used is here, script titled "Change Special Filter Value", which allows delimiting by newline, tabs, commas, quotes, and a few others. Feel free to add or subtract here, depending on your user-base's needs.
strVals = Document.Properties["SelectedSiteNames"]
lst = ""
cnt = 0
x = 0
y = 0
z = 0
for letter in strVals:
if y == 1:
if letter == " ":
lst = lst + "'" + strVals[x:z] + "', "
y = 0
elif letter == ",":
lst = lst + "'" + strVals[x:z] + "', "
y = 0
elif letter == "\n":
lst = lst + "'" + strVals[x:z] + "', "
y = 0
elif letter == "\r":
lst = lst + "'" + strVals[x:z] + "', "
y = 0
elif letter == "'":
lst = lst + "'" + strVals[x:z] + "', "
y = 0
elif letter == '"':
lst = lst + "'" + strVals[x:z] + "', "
y = 0
elif letter == '\t':
lst = lst + "'" + strVals[x:z] + "', "
y = 0
else:
if letter <> " " and letter <> "," and letter <> "\n" and letter <> "\r" and letter <> "'" and letter <> '"' and letter <> "\t":
if y == 0:
cnt += 1
print letter
x = z
y = 1
z += 1
if y == 1:
lst = lst + "'" + strVals[x:z] + "', "
print lst
lst = lst.upper()
if len(lst) > 0:
lst = lst[1:len(lst) - 3]
Document.Properties["SpecialFilterValue"] = lst
Step one is now complete! You have a list of all your selected site names in a property that you can now pass to your stored procedure.
Note: I believe there's a limit to the number of characters Spotfire can pass through a string value. In my previous testing, I think it's been over 500,000 characters (it's been a while, so I don't remember exactly), so you have a lot of leeway, but it does exist, and depending on which data source you're using, it may be lower.
Step Two: Alter the stored Procedure
Your stored procedure will basically be something along the lines of this:
Create procedure ProcA(In Start_Date date, IN End_Date date, In Site_Name text)
Begin
DECLARE #Script nvarchar(max) =
N'
Select * from TableA where day between Start_Date and End_Date and Site_Name in (' + #Site_Name + ') '
EXECUTE (#Script)
Downright easy in comparison!
(No loop after all! The bizarre use case I was remembering doesn't apply here, unless you're also using a data base that doesn't allow you to pass parameters directly...)
I am implementing a web application where I need to check if a given point is within a polygon in MySQL table?
I am using ASP.net with MySQL. I am trying to use the following SQL statement
SELECT REGION_USER_ID FROM region WHERE (ST_Within(point(-23, 1), geom));
with my table and get the following error.
(FUNCTION ST_Within DOES NOT exist)
What is the issue here?
Also, is geom is a keyword ? (I got this from a site but can not remember where)
My polygon coordinates are in the table written with the following statement : (It's working and I can read and see)
INSERT INTO region (REGION_POLYGON) VALUES (PolygonFromText(#Parameter1))
Any help is greatly appreciated.
Here it is if someone is looking for the solution :
string Query = #"SELECT " +
"A," +
"B,"+
"C,"+
"D,"+
"E,"+
"F"+
"FROM user " +
"INNER JOIN State ON " +
"A=B AND C=#Parameter1 " +
"INNER JOIN Country ON " +
"CONTAINS(REGION_POLYGON, point(#Parameter2, #Parameter3)=1)";
Parameter2 : Logitude
Parameter3 : Latitude
Thanks.
In Report Builder, I have an expression using the lookupset function that pulls back either nothing, a date and description, or several dates and several descriptions. The data it is pulling is correct. I have searched this forum and MSDN. Using what I've found in both places, I have tweaked my expression to the following.
My expression:
=Join(Lookupset(Fields!ProjectName.Value,
Fields!ProjectNames.Value,
Fields!TaskBaseline0FinishDate.Value & " - " & Fields!TaskName.Value,
"DsActivitiesCompleted"))
However, when this is displayed it doesn't have a carriage return, it just puts one after another after another. Example Below:
08/05/2015 – Milestone: Kickoff meeting Complete 08/18/2015 – Milestone: PMT Test Planning Complete 08/26/2015 – Milestone: Set CCD Date 08/26/2015 – Sprint 0 Complete 09/18/2015 – Milestone: Wave 1 Complete 09/28/2015 - Milestone: Wave 2 Complete
What I want it to look like is below. If possible I would like to have bullet points in front of each line as well.
My question is how do I get it in the format above?
Thanks,
MM
You have missed the final (optional) argument of JOIN which states which character you want to use to join your string together. Changing your expression tyo use vbCrLf (the VB new line code) as follows
=Join(Lookupset(Fields!ProjectName.Value,
Fields!ProjectNames.Value,
Fields!TaskBaseline0FinishDate.Value & " - " & Fields!TaskName.Value,
"DsActivitiesCompleted"),
vbCrLf)
Gives this output
Update
Use the below to use Chr(183) as a bullet character for each new line as well
=" " + Chr(183) + " " +
Join(Lookupset(Fields!ProjectName.Value,
Fields!ProjectNames.Value,
Fields!TaskBaseline0FinishDate.Value & " - " & Fields!TaskName.Value,
"DsActivitiesCompleted"),
vbCrLf + " " + Chr(183) + " ")
In postgis, is the ST_GeomFromText call very expensive? I ask mostly because I have a frequently called query that attempts to find the point that is nearest another point that matches some criteria, and which is also within a certain distance of that other point, and the way I currently wrote it, it's doing the same ST_GeomFromText twice:
$findNearIDMatchStmt = $postconn->prepare(
"SELECT internalid " .
"FROM waypoint " .
"WHERE id = ? AND " .
" category = ? AND ".
" (b.category in (1, 3) OR type like ?) AND ".
" ST_DWithin(point, ST_GeomFromText(?," . SRID .
" ),". SMALL_EPSILON . ") " .
" ORDER BY ST_Distance(point, ST_GeomFromText(?,", SRID .
" )) " .
" LIMIT 1");
Is there a better way to re-write this?
Slightly OT: In the preview screen, all my underscores are being rendered as & # 9 5 ; - I hope that's not going to show up that way in the post.
I don't believe ST_GeomFromText() is particularly expensive, although in the past I've optimized PostGIS queries by creating a function, declaring a variable and then assigning the result of ST_GeomFromText to the variable.
Have you tried checking the execution plan for you query with a variety of different parameters because that should give you a definite idea of which bits of the query are taking the time?
I'm guessing most of the execution time will be in the calls to ST_DWithin() and ST_Distance(), although if the id and category columns aren't indexed then it might be doing some interesting table scanning.
#Ubiguch
It appears that ST_DWithin uses the spatial index, so that seems to cut down on the number of points to be queried pretty quickly.
navaid=> explain select internalid from waypoint where id != 'KROC' AND ST_DWithin(point, ST_GeomFromText('POINT(-77.6723888888889 43.1188611111111)',4326), 0.05) order by st_distance(point, st_geomfromtext('POINT(-77.6723888888889 43.1188611111111)',4326)) limit 1;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=8.37..8.38 rows=1 width=104)
-> Sort (cost=8.37..8.38 rows=1 width=104)
Sort Key: (st_distance(point, '0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry))
-> Index Scan using waypoint_point_idx on waypoint (cost=0.00..8.36 rows=1 width=104)
Index Cond: (point && '0103000020E61000000100000005000000000000C03B6E53C000000060D0884540000000C03B6E53C0000000409D95454000000020D56753C0000000409D95454000000020D56753C000000060D0884540000000C03B6E53C000000060D0884540'::geometry)
Filter: (((id)::text <> 'KROC'::text) AND (point && '0103000020E61000000100000005000000000000C03B6E53C000000060D0884540000000C03B6E53C0000000409D95454000000020D56753C0000000409D95454000000020D56753C000000060D0884540000000C03B6E53C000000060D0884540'::geometry) AND ('0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry && st_expand(point, 0.05::double precision)) AND (st_distance(point, '0101000020E61000002FFE676B086B53C0847E44D7368F4540'::geometry) < 0.05::double precision))
(6 rows)
Without the order by and the limit, it looks like a typical query is only returning 5-10 waypoints max. So I probably shouldn't worry about the additional cost of the filter that's applied to the points returned.