SQL Server - Query by Geometry Data - sql

Say I have following data in table addresses:
physicalState physicalPostalCode geometry
------------------------------------------------------------------------------
PA 15340 0xE6100000010CAC1C5A643B1354C02D431CEBE2264440
OK 74576 0xE6100000010C7DD0B359F50158C079E9263108544140
WV 26033 0xE6100000010CE8D9ACFA5C2554C0273108AC1CEA4340
WV 26033 0xE6100000010C36AB3E575B2554C0C3D32B6519EA4340
I want to
select *
from addresses
where geometry = GEOMETRY::STPointFromText('POINT (40.3038 -80.3005)', 4326)
Finding it very difficult to figure this out...

Try use method [STContains]
like this condition:
geometry.STContains(GEOMETRY::STPointFromText('POINT (40.3038 -80.3005)', 4326))

OKIE! Figured this one out... One thing worth noting, x/y coordinates were flip flopped. That helped to frustrate things. stupid me.
Either way, this is what in order able to query the database by specific points:
select * from addresses
WHERE geometry.ToString() = 'POINT (-80.3005 40.3038)'
Also, to credit #Adam Silenko, his solution also works as such:
select *
from addresses
where geometry.STContains(GEOMETRY::STPointFromText('POINT (-80.3005 40.3038)', 4326)) = 1
Thanks!

Related

Selecting rows from Parent Table only if multiple rows in Child Table match

Im building a code that learns tic tac toe, by saving info in a database.
I have two tables, Games(ID,Winner) and Turns(ID,Turn,GameID,Place,Shape).
I want to find parent by multiple child infos.
For Example:
SELECT GameID FROM Turns WHERE
GameID IN (WHEN Turn = 1 THEN Place = 1) AND GameID IN (WHEN Turn = 2 THEN Place = 4);
Is something like this possible?
Im using ms-access.
Turm - Game turn GameID - Game ID Place - Place on matrix
1=top right, 9=bottom left Shape - X or circle
Thanks in advance
This very simple query will do the trick in a single scan, and doesn't require you to violate First Normal Form by storing multiple values in a string (shudder).
SELECT T.GameID
FROM Turns AS T
WHERE
(T.Turn = 1 AND T.Place = 1)
OR (T.Turn = 2 AND T.Place = 4)
GROUP BY T.GameID
HAVING Count(*) = 2;
There is no need to join to determine this information, as is suggested by other answers.
Please use proper database design principles in your database, and don't violate First Normal Form by storing multiple values together in a single string!
The general solution to your problem can be accomplished by using a sub-query that contains a self-join between two instances of the Turns table:
SELECT * FROM Games
WHERE GameID IN
(
SELECT Turns1.GameID
FROM Turns AS Turns1
INNER JOIN Turns AS Turns2
ON Turns1.GameID = Turns2.GameID
WHERE (
(Turns1.Turn=1 AND Turns1.Place = 1)
AND
(Turns2.Turn=2 AND Turns2.Place = 4))
);
The Self Join between Turns (aliased Turns1 and Turns2) is key, because if you just try to apply both sets of conditions at once like this:
WHERE (
(Turns.Turn=1 AND Turns.Place = 1)
AND
(Turns.Turn=2 AND Turns.Place = 4))
you will never get any rows back. This is because in your table there is no way for an individual row to satisfy both conditions at the same time.
My experience using Access is that to do a complex query like this you have to use the SQL View and type the query in on your own, rather than use the Query Designer. It may be possible to do in the Designer, but it's always been far easier for me to write the code myself.
select GameID from Games g where exists (select * from turns t where
t.gameid = g.gameId and ((turn =1 and place = 1) or (turn =2 and place =5)))
This will select all the games that have atleast one turn with the coresponding criteria.
More info on exist:
http://www.techonthenet.com/sql/exists.php
I bypassed this problem by adding a column which holds the turns as a string example : "154728" and i search for it instead. I think this solution is also less demanding on the database

SQL: Pull data from two table

I have two tables which are question_table and student_response( like in the images below). I am having a trouble to come up with a query which can pull out Question, ChosenOption(this will display the actual option from question_table, not just OptionA,OptionB...), and TextResponse. Any help or tip is appreciated. Thank you so much !
http://i.stack.imgur.com/kthi1.png
http://i.stack.imgur.com/oXPiX.png
do you mean you want something like this?
select * from question_table,chosen_table where question_table.QuestionID=chosen_table.ID
or
select * from chosen_table join question_table on chosen_table.QuestionID = question_table.ID
Use the next
SELECT q.*,sr.choosenoption
FROM question_table q
INNER JOIN student_response sr ON sr.questionID=q.ID
probably your question will be deleted or something ... is basic SQL logic and also you don't put proper tags.
Put mysql tag on your question :)

Relational algebra - select (select)

Suppose I have a relation map called M with from and to.
I want to find all rooms that can be accessed with 1 intermediate room. Would the following lines be correct?
P = πTo (σFrom='Vestibule'(M))
X = P U πTo (σFrom=P(M))
X = πTo (σFrom= (σFrom='Vestibule'(M)) (M))
In other words, can I use the outcome of a select in another select, or do I have to use a product?
Thanks in advance.
if i understand right, you need a inner query or nested queries into inside
following link explains logic of inner and outer queries it may help you.
http://www.codecandle.com/articles/sql/subqueries/sql-subquery.html

Threshold summing in rails/postgres

I'm making a walkathon rails app. Each walker is sponsored by people who pledge money per lap up to a maximum amount.
I have a table called sponsorships that has columns walker_id, amount_per_lap, and max_amount. I want to write a SQL query to determine how much money a walker has raised.
There is also a walkers table that has id, name, and laps columns.
I know this isn't valid SQL, but I wanted something like this, but don't know the best way to do it. The walker_id and laps could be provided before executing the query.
SELECT SUM(MIN(Laps * sponsorships.amount_per_lap, sponsorships.max_amount)) FROM sponsorships
where sponsorships.walker_id = 1;
I'm making this in rails, so I was trying to figure out how to do something like this in Arel, but couldn't figure it out.
Any help would be greatly appreciated.
Edit: clarifying the walkers table.
Edit2: Accidentally had max instead of min in the pseudo code
I think the SQL you're looking for is this:
select w.id, w.name, sum(least(w.laps * s.amount_per_lap, s.max_amount))
from walkers w
join sponsorships s on w.id = s.walker_id
group by w.id, w.name
The least function is what applies your "no more than max_amount" condition. Translating that to AR should be a simple matter for you now that you know what to SELECT; I tend to go straight to SQL for anything like this.
I would try something like:
class Sponsorship < ActiveRecord::Base
name
walker_id
amount_per_lap
max_amount
class Walker < ActiveRecord::Base
name
number_of_laps
walker_sum = 0
walker=walker.find(1) # For 1 walker.
walker.sponsorships.each do |sponsor| #
walker_sum+=
min((sponsor.amount_per_lap * walker.number_of_laps), (sponsor.max_amount))
end

Django annotate() multiple times causes wrong answers

Django has the great new annotate() function for querysets. However I can't get it to work properly for multiple annotations in a single queryset.
For example,
tour_list = Tour.objects.all().annotate( Count('tourcomment') ).annotate( Count('history') )
A tour can contain multiple tourcomment and history entries. I'm trying to get how many comments and history entries exist for this tour. The resulting
history__count and tourcomment__count
values will be incorrect. If there's only one annotate() call the value will be correct.
There seems to be some kind of multiplicative effect coming from the two LEFT OUTER JOINs. For example, if a tour has 3 histories and 3 comments, 9 will be the count value for both. 12 histories + 1 comment = 12 for both values. 1 history + 0 comment = 1 history, 0 comments (this one happens to return the correct values).
The resulting SQL call is:
SELECT `testapp_tour`.`id`, `testapp_tour`.`operator_id`, `testapp_tour`.`name`, `testapp_tour`.`region_id`, `testapp_tour`.`description`, `testapp_tour`.`net_price`, `testapp_tour`.`sales_price`, `testapp_tour`.`enabled`, `testapp_tour`.`num_views`, `testapp_tour`.`create_date`, `testapp_tour`.`modify_date`, `testapp_tour`.`image1`, `testapp_tour`.`image2`, `testapp_tour`.`image3`, `testapp_tour`.`image4`, `testapp_tour`.`notes`, `testapp_tour`.`pickup_time`, `testapp_tour`.`dropoff_time`, COUNT(`testapp_tourcomment`.`id`) AS `tourcomment__count`, COUNT(`testapp_history`.`id`) AS `history__count`
FROM `testapp_tour` LEFT OUTER JOIN `testapp_tourcomment` ON (`testapp_tour`.`id` = `testapp_tourcomment`.`tour_id`) LEFT OUTER JOIN `testapp_history` ON (`testapp_tour`.`id` = `testapp_history`.`tour_id`)
GROUP BY `testapp_tour`.`id`
ORDER BY `testapp_tour`.`name` ASC
I have tried combining the results from two querysets that contain a single call to annotate (), but it doesn't work right... You can't really guarantee that the order will be the same. and it seems overly complicated and messy so I've been looking for something better...
tour_list = Tour.objects.all().filter(operator__user__exact = request.user ).filter(enabled__exact = True).annotate( Count('tourcomment') )
tour_list_historycount = Tour.objects.all().filter( enabled__exact = True ).annotate( Count('history') )
for i,o in enumerate(tour_list):
o.history__count = tour_list_historycount[i].history__count
Thanks for any help. Stackoverflow has saved my butt in the past with a lot of already-answered questions, but I wasn't able to find an answer to this one yet.
Thanks for your comment. That didn't quite work but it steered me in the right direction. I was finally able to solve this by adding distinct to both Count() calls:
Count('tourcomment', distinct=True)
tour_list = Tour.objects.all().annotate(tour_count=Count('tourcomment',distinct=True) ).annotate(history_count=Count('history',distinct=True) )
You have to add distinct=True to get the proper result else it will return the wrong answer.
I can't guarantee that this will solve your problem, but try appending .order_by() to your call. That is:
tour_list = Tour.objects.all().annotate(Count('tourcomment')).annotate(Count('history')).order_by()
The reason for this is that django needs to select all the fields in the ORDER BY clause, which causes otherwise identical results to be selected. By appending .order_by(), you're removing the ORDER BY clause altogether, which prevents this from happening. See the aggregation documentation for more information on this issue.