Fw: Need Help with a query

2005-12-11 Thread Rhino
Oops, I meant to copy the list on this reply so that others could 
benefit


Rhino

- Original Message - 
From: "Rhino" <[EMAIL PROTECTED]>

To: "Mark Phillips" <[EMAIL PROTECTED]>
Sent: Sunday, December 11, 2005 6:19 PM
Subject: Re: Need Help with a query




- Original Message - 
From: "Mark Phillips" <[EMAIL PROTECTED]>

To: "MYSQL List" 
Sent: Sunday, December 11, 2005 12:38 PM
Subject: Need Help with a query



I have a table with several columns. The ones of interest are flight_id,
angle, and baseline. I want to find the flight_ids for the flights with 
the
maximum and minimum altitudes, where 
altitude=baseline*tan(radians(angle)).


For example,
Flights
+++---+
| flight_id | angle| baseline  |
+++---+
|   1 | 37.0 | 100.0 |
|   2 | 50.0 | 100.0 |
|   3 | 48.0 | 100.0 |
|   4 | 40.0 | 100.0 |
|   5 | 44.0 | 100.0 |
|   6 | 40.0 | 100.0 |
|   7 | 45.0 | 100.0 |
|   8 | 44.0 |  75.0 |
|   9 | 57.8 |  75.0 |
+++---+

The result I am looking for are:

Maximum altitude:
+++
| flight_id | altitude |
+++
|   2 | 119.17536 |
|   9 | 119.17536|
+++

Minimum altitude:
+---+---+
| flight_id | altitudeM |
+---+---+
| 8 |  72.42666 |
+---+---+

Thanks for any help you can provide!

I do wish posters to this list would get in the habit of volunteering 
which version of MySQL they are using, particularly for SQL questions!


The answer to almost every SQL question is "it depends on which version of 
MySQL you are using". It's very tedious to give the answer for every 
version MySQL, as in: If you're using Version 3.x, the answer is A. If 
you're using Version 4.0.x the answer is B. If you're using Version 4.1.x, 
the answer is C. etc.


[By the way, I don't mean to single you out with this mini-rant; it's just 
a general observation.]


Therefore, I'm going to assume you are using Version 4.1 or higher; in 
other words, you use a version which supports subqueries. If you are on an 
earlier version, please reply to the list and explain which version you 
are on. Perhaps someone will be willing to show you alternatives that will 
work for you.


I should also explain that I am _not_ on a version of MySQL which supports 
subqueries. However, my main database is DB2 which does support subqueries 
and the SQL used by DB2 and MySQL is very very similar so this _untested_ 
answer should be pretty close to what you need.


I think the best answer to your question is to use subqueries. I'm going 
to express the answer in pseudocode first to give you a general sense of 
the answer, then give you something that should be pretty close to a final 
answer that will work on your system.


Pseudocode (for maximum altitude):

select flight_id, baseline*tan(radians(angle)) as max_altitude
from Flights
where baseline*tan(radians(angle)) in (subquery that gets largest altitude 
from table)


In real SQL, that should end up looking like this:

select flight_id, baseline*tan(radians(angle)) as max_altitude
from Flights
where baseline*tan(radians(angle)) in (select 
max(baseline*tan(radians(angle))) from Flights)


To get the query for the minimum altitude, use the exact same query except 
replace the max function with the min function in the subquery and change 
the 'as' for the outer query from 'max_altitude' to 'min_altitude'.


For what it's worth, I got slightly different numbers in DB2 so I did not 
have a tie for maximum altitude: my maximum altitude was for flight 2 at 
119.17535 (versus 119.09797 for flight 9). Perhaps the tan() or radians() 
functions in DB2 are slightly more precise?


The 'in' that introduces the subqueries could potentially be replaced by 
'=' but 'in' is safer. If you use 'in' and there is more than one flight 
tied for the highest altitude, the query works fine. If you use '=' and 
there is more than one flight tied for the highest altitude, the query 
will almost certainly fail - it does in DB2! - because '=' implies that 
only one row in the outer query can have the maximum altitude; therefore 
the query fails if more than one row matches.


The most tedious part of these queries is typing the 
'baseline*tan(radians(angle))' expression. You might expect that there 
would be some shortcut that would enable you to type the expression only 
once and then make repeated references to it. Sometimes that is possible 
but without a suitable version of MySQL handy, I don't want to propose any 
possible ways to do that since I can't be sure they'll work. Perhaps 
people with newer versions of MySQL can suggest shortcuts that reduce the 
amount of typing.


Rhino 




--

Fw: Need help with a query..

2005-06-16 Thread SGreen
(forwarded to the list - I am not the OP)
- Forwarded by Shawn Green/Unimin on 06/16/2005 11:45 AM -

James Black <[EMAIL PROTECTED]> wrote on 06/16/2005 11:44:36 AM:

> -BEGIN PGP SIGNED MESSAGE-
> Hash: SHA1

> [EMAIL PROTECTED] wrote:
> > [EMAIL PROTECTED] wrote on 06/16/2005 11:30:10 AM:
> >
> >
> >>Cory Robin <[EMAIL PROTECTED]> wrote on 16/06/2005 08:09:22:
> >
> >
> >>>I need to speed up a search, big time.
> >>>
> >>>I have an application that searches for records on a date field.  If
> >
> > it
> >
> >>>doesn't find an exact date match, it keeps searching adjacent days
> >
> > until
> >
> >>it
> >>
> >>>finds a certain amount of records.
> >>>
> >>>The problem now is, I'm using my application to loop through and run
> >>>multiple queries and it's dog ass slow..I'm hoping that one of 
you
> >>
> >>SQL
> >>
> >>>gurus can point me in the right direction to create a query that will
> >>
> >>work
> >>
> >>>it out for me.  Here's the logic the best I can explain..
> >>>
> >>>I want to return a minimum of 15 records..  I'm searching for records
> >
> > on
> >
> >>or
> >>
> >>>around 2005-10-01
> >>>
> >>>Select * from table_x where row_date = '2005-10-01'
> >>>/* at this point if matched records are >= 15 then simply return the
> >>
> >>records
> >>
> >>>on that date..  If not..*/
> >>>Select * from table_x where row_date = '2005-09-31'
> >>>
> >>>Select * from table_x where row_date = '2005-10-02'
> >>>
> >>>And so on until it finds >= 15 records or it searches through 5 days
> >
> > (+-
> >
> >>3
> >>
> >>>on search date)
> >>>
> >>>I hope this makes sense..  I'm new to all this stuff.
> >>>
> >>>Eventually I'm going to do the same thing for times as well..
> >
> >
> >>Heres a suggestion:
> >
> >
> >>select * from table_x
> >>where  row_date between date_sub(now(), interval 3 day) AND
> >>date_add(now(), interval 3 day)
> >>order by abs(time_to_sec(datediff(created, now(
> >>limit 15 ;
> >
> >
> >>This does times relative to now(), but I am sure you can generalise 
it.
> >>The first line specifies the desired fields
> >>The second selects (in principle) all the records within your largest
> >>target window
> >>The third orders them by closeness to your target time
> >>and the last says you only want 15 of them.
> >
> >
> >>This version is based on exact seconds from the target time (now() in 
my
> >>case): the version which works in whole days would only be slightly
> >>different.
> >
> >
> >>Alec
> >
> >
> > Only one problem with your solution, LIMIT tells how many records AT 
MOST
> > to return, he wants to get 15 AT LEAST and stop appending records once 
he
> > gets over 15 total results.

> I didn't think about the AT LEAST 15 rows.

> I have two ideas:
> 1) Do an order by and just fetch each day until at least 15 is reached.
> 2) Two queries, the first involves a GROUP BY, 'SELECT row_date,
> count(*) FROM table_x GROUP BY row_date' and see which date you need to
> do the select for, then just get all the rows from that date forward.

> - --
> "Love is mutual self-giving that ends in self-recovery." Fulton Sheen
> James Black[EMAIL PROTECTED]
> -BEGIN PGP SIGNATURE-
> Version: GnuPG v1.4.1 (MingW32)
> Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

> iD8DBQFCsZ5kikQgpVn8xrARAh/aAJ9bp1rPVdD+oBfuc3iDourPwRFIugCfR2qF
> oQvoGEWlRTpktAakMJA2Q5A=
> =8bF7
> -END PGP SIGNATURE-