Unix Technical Forum

Complex SQL?

This is a discussion on Complex SQL? within the MySQL forums, part of the Database Server Software category; --> Hi, I have a table which contains subscriptions from students, bu they are tagged with a date (so I ...


Go Back   Unix Technical Forum > Database Server Software > MySQL

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-28-2008, 08:11 AM
Toni Van Remortel
 
Posts: n/a
Default Complex SQL?

Hi,

I have a table which contains subscriptions from students, bu they are
tagged with a date (so I have a kind of history).
Both 'email' and 'datum' are primary keys.

How can I get a full list of every subscription, but only the last of each
student?

My SQL knowledge is too small to solve this, I'm affraid. Any help welcome.

Regards,
Toni.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 02-28-2008, 08:11 AM
Giuseppe Maxia
 
Posts: n/a
Default Re: Complex SQL?

Toni Van Remortel wrote:
> Hi,
>
> I have a table which contains subscriptions from students, bu they are
> tagged with a date (so I have a kind of history).
> Both 'email' and 'datum' are primary keys.
>
> How can I get a full list of every subscription, but only the last of each
> student?
>
> My SQL knowledge is too small to solve this, I'm affraid. Any help welcome.
>
> Regards,
> Toni.


assuming that datum is a date using a DATE or DATETIME or TIMESTAMP type,
then you can use the MAX function:

select email, max(datum) from subscriptions group by email;


If you are not using any of the above column types, you may not be able to
do what you want.

ciao
gmax

--
_ _ _ _
(_|| | |(_|><
_|
http://gmax.oltrelinux.com
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 02-28-2008, 08:12 AM
Toni Van Remortel
 
Posts: n/a
Default Re: Complex SQL?

Giuseppe Maxia wrote:

> Toni Van Remortel wrote:
>> Hi,
>>
>> I have a table which contains subscriptions from students, bu they are
>> tagged with a date (so I have a kind of history).
>> Both 'email' and 'datum' are primary keys.
>>
>> How can I get a full list of every subscription, but only the last of
>> each student?
>>
>> My SQL knowledge is too small to solve this, I'm affraid. Any help
>> welcome.
>>
>> Regards,
>> Toni.

>
> assuming that datum is a date using a DATE or DATETIME or TIMESTAMP type,
> then you can use the MAX function:
>
> select email, max(datum) from subscriptions group by email;


Wonderfull. I was seeking for JOIN and subquery's etc.
Seems it to be a simple GROUP BY command.

Thank you!
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 02-28-2008, 08:12 AM
Toni Van Remortel
 
Posts: n/a
Default Re: Complex SQL?

Giuseppe Maxia wrote:

> Toni Van Remortel wrote:
>> Hi,
>>
>> I have a table which contains subscriptions from students, bu they are
>> tagged with a date (so I have a kind of history).
>> Both 'email' and 'datum' are primary keys.
>>
>> How can I get a full list of every subscription, but only the last of
>> each student?
>>
>> My SQL knowledge is too small to solve this, I'm affraid. Any help
>> welcome.
>>
>> Regards,
>> Toni.

>
> assuming that datum is a date using a DATE or DATETIME or TIMESTAMP type,
> then you can use the MAX function:
>
> select email, max(datum) from subscriptions group by email;
>
>
> If you are not using any of the above column types, you may not be able to
> do what you want.


Still a problem:

SELECT email, naam, def_id, workshop_id_1, workshop_id_2, workshop_id_3,
max( datum ) as datum FROM 2006_subscriptions GROUP BY email ORDER BY datum

selects the max(datum) as it should, but not the values of workshop_id_X
that belong to the max(datum) row.

Idea?
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 02-28-2008, 08:12 AM
Giuseppe Maxia
 
Posts: n/a
Default Re: Complex SQL?

Toni Van Remortel wrote:
[SNIP]
>
>
> Still a problem:
>
> SELECT email, naam, def_id, workshop_id_1, workshop_id_2, workshop_id_3,
> max( datum ) as datum FROM 2006_subscriptions GROUP BY email ORDER BY datum
>
> selects the max(datum) as it should, but not the values of workshop_id_X
> that belong to the max(datum) row.
>
> Idea?


Only the columns that you use in the GROUP BY clause are meaningful in
such a query.
If you need more columns, then you must use a subquery.

SELECT
email, naam, def_id,
workshop_id_1, workshop_id_2,
workshop_id_3, datum
FROM
2006_subscriptions
WHERE
(email, datum) IN (select email, max(datum) from 2006_subscriptions GROUP BY email)
ORDER BY
datum

ciao
gmax

--
_ _ _ _
(_|| | |(_|><
_|
http://gmax.oltrelinux.com
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 02-28-2008, 08:12 AM
Bill Karwin
 
Posts: n/a
Default Re: Complex SQL?

Toni Van Remortel wrote:
> SELECT email, naam, def_id, workshop_id_1, workshop_id_2, workshop_id_3,
> max( datum ) as datum FROM 2006_subscriptions GROUP BY email ORDER BY datum


There's a rule about GROUP BY that you should understand. It applies to
any database product, not just MySQL.

Every field in your select list that is not part of an aggregate
function (e.g. MAX, MIN, COUNT, SUM, AVG), _must_ be in the group by
list, or else you get an ambiguous result.

Consider the following example:

|__A__|__B__|__C__|
| a | 1 | x |
| a | 1 | y |
| a | 2 | z |
| a | 2 | w |


SELECT COUNT(A), B FROM MyTABLE GROUP BY B;

Prints:

|_COUNT_|__B__|
| 2 | 1 |
| 2 | 2 |

SELECT COUNT(A), B, C FROM MyTABLE GROUP BY B;

|_COUNT_|__B__|__C__|
| 2 | 1 | x |
| 2 | 2 | z |

What happened to 'y' and 'w'? The answer is that if you list a field
such as `C` in the select list, without also listing it in the GROUP BY
clause, then it's ambiguous to the SQL engine which row to take the
value of `C` from, when presenting the final result. When grouping
solely by `B`, there are two rows in each group, but only one row in the
result. The field returning the value of `C` can holds only one value
per row, and your query hasn't done anything to specify which row from
which to take that value. So the SQL engine decides for you, somewhat
arbitrarily.

In some RDBMS products, a query such as this that creates an ambiguous
result set actually results in an error, and won't execute the query or
return any result. You _must_ change the query to make it unambiguous.

But in MySQL, the query is permitted, and it is assumed that you know
what you are doing and you accept the ambiguous result, even though it
has lost some information from the underlying data.

Regards,
Bill K.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 01:42 PM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com