473,803 Members | 2,913 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

SQL statement question

Hello group,

I have a table with the next contents.
It lists data about : Who sent what kind of message at what time.
For the Level column: The highest level is Critical, the middle is Warning,
the lowest is Info.

Id Timestamp Level
1 12:00 Info
1 13:00 Warning
1 14:00 Critical
2 12:00 Info
2 13:00 Warning
2 14:00 Info
2 15:00 Warning
3 12:00 Critical
3 13:00 Warning
4 15:00 Info
5 15:00 Info
5 16:00 Warning

What I want to get out of his list is:
The first message with the highest level of each Id. So let the Level-column
prevail above the Timestamp column,so I want to get this result:

1 14:00 Critical // The only 'Critical'
2 13:00 Warning // the first 'Warning'
3 12:00 Critical // The only 'Critical'
4 15:00 Info // The only one, so simple
5 16:00 Warning // The highest level, the only
'Warning'
So: First find the highest level of message of each Id and then find the
first one.
The first part I tried with CASE .. THEN .. END construction.

Any hints appreciated.

Gr, Hans
Jul 20 '05 #1
6 2054
"Siemel Naran" <Si*********@RE MOVE.att.net> wrote in message
news:S%8Oc.1518 48
"Hans" <ni*********@zo nnet.nl> wrote in message news:4108fb97$0 $93324
"Leif" <id****@interne t.dk> wrote in message
select id,min(time),le vel from table a where (id,level) in (select
id,max(level) from table b group by b.id) group by a.id
BTW-2 The query you propesed is running now for more than an hour, so
What is the exact query you ran? I think MySql supports function indexes,
so for example you could try to create index (id, case level when 'High'
then 3 ... end), or create index (id, if(level='High' , 3, if(...))). Will
need to look it up, but have to run to work.
So I checked, and no, MySql 4.1 and even 5.0 I think, does not support
function indexes.
Also, what does the query plan say is the driving table and index?


The above is important, because it could mean the difference between a query
that returns right away, and another that takes hours.

In Leif's original query, I think you would need only one index. This
assumes driving by the inner query is the right thing for your situation
(which may or may not be the case), and that MySql will in this case indeed
drive by the inner query.

create index table_level on table (id, level);

But this only works when the level numbers are 1 for Critical, 2 for
Warning, 3 for Info. By contrast, sorting level as strings yields Critical,
Info, Warning -- which is not correct.
One solution is function indices, which some databases provide, but not
MySql. It would look like this:

create index table_level on table (id, case level when 'Critical' then 1 ...
end);
Most databases support triggers, but MySql only will in 5.1. It would look
something like this:

create trigger on table
for update
as update table set levelnum = case level when 'Critical' then 1 ... end;

create index table_level on table (id, levelnum);
Some databases also let you define calculated fields, so you'd say

create table (
level varchar(10) not null,
levelnum smallint(1) as case level when 'Critical' then 1 ... end,
index on table (id, levelnum);
);

But I don't think MySql does not let you do this either.
Of course, you could just add your levelnum column and when you insert or
update table.level, remember to update levelnum too. So you'd have to put
more work into the PHP or C++ scripts, or whatever, that take input from the
user and convert these into SQL statements.
Another design decision is to set level = "1 - Critical", "2 - Warning",
etc. It's nice for the end user too. We use it at work, and it works
nicely. Then Leif's original solution plus the index should work. You
could create an index the first char of table.level.
The problem with

select id,max(case level when ... end) from table b group by b.id

is that the system will still scan all rows and evaluate (case level ...
end) because it does not know that once it has seen a 'Critical' it can't
see anything higher. Plus, without a function or index or index on a
calculated column, it has no index to immediately locate the records of
importance, so it has to do a full table scan.
Still, maybe we could use collations. Something like

create table (
level varchar(10) not null character set collate <an appropriate name>
)

The <an appropriate name> is a collation where Critical comes first, then
Warning, then Info. But I don't know how to create new collations.
Jul 20 '05 #2

"Hans" <ni*********@zo nnet.nl> skrev i en meddelelse
news:41******** *************** @news.xs4all.nl ...
Hello group,

I have a table with the next contents.
It lists data about : Who sent what kind of message at what time.
For the Level column: The highest level is Critical, the middle is Warning, the lowest is Info.

Id Timestamp Level
1 12:00 Info
1 13:00 Warning
1 14:00 Critical
2 12:00 Info
2 13:00 Warning
2 14:00 Info
2 15:00 Warning
3 12:00 Critical
3 13:00 Warning
4 15:00 Info
5 15:00 Info
5 16:00 Warning

What I want to get out of his list is:
The first message with the highest level of each Id. So let the Level-column prevail above the Timestamp column,so I want to get this result:

1 14:00 Critical // The only 'Critical'
2 13:00 Warning // the first 'Warning'
3 12:00 Critical // The only 'Critical'
4 15:00 Info // The only one, so simple 5 16:00 Warning // The highest level, the only
'Warning'
So: First find the highest level of message of each Id and then find the
first one.

I hope the level is an enum, so you can sort on it.

Will this work?

select id,min(time),le vel from table a where (id,level) in (select
id,max(level) from table b group by b.id) group by a.id

Leif
Jul 20 '05 #3

"Leif" <id****@interne t.dk> wrote in message
news:41******** **************@ nntp03.dk.telia .net...

"Hans" <ni*********@zo nnet.nl> skrev i en meddelelse
news:41******** *************** @news.xs4all.nl ...
Hello group,


I hope the level is an enum, so you can sort on it.
Nope.
Will this work?

select id,min(time),le vel from table a where (id,level) in (select
id,max(level) from table b group by b.id) group by a.id


That's a query that will cost a lot of time for multiple 1000s of records.

I already found a solution myself; I created a new table with the
'enum'-values of all levels ,MessageLevels:
Value Name
1 Info
2 Warning
3 Critical

And thenthis query:
SELECT
`SubQuery`.`Id_ 1`,
`MessageLevels` .`Name`
FROM (
SELECT
`MyTable`.`Id` AS `Id_1`,
`MessageLevels` .`Value` AS `Message_Value`
FROM
`MyTable`
INNER JOIN `MessageLevels` ON (`MyTable`.`Nam e` = `MessageLevels` .`Name`)
ORDER BY `Id`,
`Message_Value` DESC
) AS `SubQuery`
INNER JOIN
`MessageLevels` ON (`SubQuery`.`Me ssage_Value` = `MessageLevels` .`Value`)
GROUP BY `SubQuery`.`Id_ 1`
Which in the subquery creates a table with all ID's with ALL their
messagelevels, sorted by ID, and then MessageLevel DESC,
And the from this subquery's result, id do GROUP BY Id, which causes only
the first record for each Id to be selected.

BTW This is not exactly what I asked in my first post, (No timestamp) but it
is indeed what I want ;-)

BTW-2 The query you propesed is running now for more than an hour, so that's
not really a good solution, but thanks anyway for thinking with me.

Gr, Hans
Jul 20 '05 #4

"Leif" <id****@interne t.dk> wrote in message
news:41******** **************@ nntp03.dk.telia .net...

"Hans" <ni*********@zo nnet.nl> skrev i en meddelelse
news:41******** *************** @news.xs4all.nl ...
Hello group,


I hope the level is an enum, so you can sort on it.
Nope.
Will this work?

select id,min(time),le vel from table a where (id,level) in (select
id,max(level) from table b group by b.id) group by a.id


That's a query that will cost a lot of time for multiple 1000s of records.

I already found a solution myself; I created a new table with the
'enum'-values of all levels ,MessageLevels:
Value Name
1 Info
2 Warning
3 Critical

And thenthis query:
SELECT
`SubQuery`.`Id_ 1`,
`MessageLevels` .`Name`
FROM (
SELECT
`MyTable`.`Id` AS `Id_1`,
`MessageLevels` .`Value` AS `Message_Value`
FROM
`MyTable`
INNER JOIN `MessageLevels` ON (`MyTable`.`Nam e` = `MessageLevels` .`Name`)
ORDER BY `Id`,
`Message_Value` DESC
) AS `SubQuery`
INNER JOIN
`MessageLevels` ON (`SubQuery`.`Me ssage_Value` = `MessageLevels` .`Value`)
GROUP BY `SubQuery`.`Id_ 1`
Which in the subquery creates a table with all ID's with ALL their
messagelevels, sorted by ID, and then MessageLevel DESC,
And the from this subquery's result, id do GROUP BY Id, which causes only
the first record for each Id to be selected.

BTW This is not exactly what I asked in my first post, (No timestamp) but it
is indeed what I want ;-)

BTW-2 The query you propesed is running now for almost 45 minutes, so that's
not really a good solution, but thanks anyway for thinking with me.

Gr, Hans

Jul 20 '05 #5
"Hans" <ni*********@zo nnet.nl> wrote in message news:4108fb97$0 $93324
"Leif" <id****@interne t.dk> wrote in message
Will this work?

select id,min(time),le vel from table a where (id,level) in (select
id,max(level) from table b group by b.id) group by a.id


That's a query that will cost a lot of time for multiple 1000s of records.

BTW-2 The query you propesed is running now for more than an hour, so that's not really a good solution, but thanks anyway for thinking with me.


What is the exact query you ran? I think MySql supports function indexes,
so for example you could try to create index (id, case level when 'High'
then 3 ... end), or create index (id, if(level='High' , 3, if(...))). Will
need to look it up, but have to run to work.

Also, what does the query plan say is the driving table and index?
Jul 20 '05 #6
"Siemel Naran" <Si*********@RE MOVE.att.net> wrote in message
news:S%8Oc.1518 48
"Hans" <ni*********@zo nnet.nl> wrote in message news:4108fb97$0 $93324
"Leif" <id****@interne t.dk> wrote in message
select id,min(time),le vel from table a where (id,level) in (select
id,max(level) from table b group by b.id) group by a.id
BTW-2 The query you propesed is running now for more than an hour, so
What is the exact query you ran? I think MySql supports function indexes,
so for example you could try to create index (id, case level when 'High'
then 3 ... end), or create index (id, if(level='High' , 3, if(...))). Will
need to look it up, but have to run to work.
So I checked, and no, MySql 4.1 and even 5.0 I think, does not support
function indexes.
Also, what does the query plan say is the driving table and index?


The above is important, because it could mean the difference between a query
that returns right away, and another that takes hours.

In Leif's original query, I think you would need only one index. This
assumes driving by the inner query is the right thing for your situation
(which may or may not be the case), and that MySql will in this case indeed
drive by the inner query.

create index table_level on table (id, level);

But this only works when the level numbers are 1 for Critical, 2 for
Warning, 3 for Info. By contrast, sorting level as strings yields Critical,
Info, Warning -- which is not correct.
One solution is function indices, which some databases provide, but not
MySql. It would look like this:

create index table_level on table (id, case level when 'Critical' then 1 ...
end);
Most databases support triggers, but MySql only will in 5.1. It would look
something like this:

create trigger on table
for update
as update table set levelnum = case level when 'Critical' then 1 ... end;

create index table_level on table (id, levelnum);
Some databases also let you define calculated fields, so you'd say

create table (
level varchar(10) not null,
levelnum smallint(1) as case level when 'Critical' then 1 ... end,
index on table (id, levelnum);
);

But I don't think MySql does not let you do this either.
Of course, you could just add your levelnum column and when you insert or
update table.level, remember to update levelnum too. So you'd have to put
more work into the PHP or C++ scripts, or whatever, that take input from the
user and convert these into SQL statements.
Another design decision is to set level = "1 - Critical", "2 - Warning",
etc. It's nice for the end user too. We use it at work, and it works
nicely. Then Leif's original solution plus the index should work. You
could create an index the first char of table.level.
The problem with

select id,max(case level when ... end) from table b group by b.id

is that the system will still scan all rows and evaluate (case level ...
end) because it does not know that once it has seen a 'Critical' it can't
see anything higher. Plus, without a function or index or index on a
calculated column, it has no index to immediately locate the records of
importance, so it has to do a full table scan.
Still, maybe we could use collations. Something like

create table (
level varchar(10) not null character set collate <an appropriate name>
)

The <an appropriate name> is a collation where Critical comes first, then
Warning, then Info. But I don't know how to create new collations.
Jul 20 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
4409
by: Greg Ofiesh | last post by:
Anyone who can help, I have two tables T1 and T2. T1 has fields K1 and F2 and T2 has fields K2 and F1. F1 is the foreign key relating to K1 and F2 is the foreign key relating to K2. My initial question has been how can I add a row to both tables with accurate Fx values in one SQL INSERT statement? I have been told it cannot be done.
94
13914
by: John Bailo | last post by:
The c# *return* statement has been bothering me the past few months. I don't like the fact that you can have different code paths in a method and have multiple return statements. To me, it would be more orthogonal if a method could only have one return statement. --
9
2365
by: Michael | last post by:
Hi all, I would like to get people's opinion about executing SQL statements in C# (or any other .NET language really). I used to create my SQL statement by building a string and replacing single quote with two single quotes. Sometimes, I used SqlParameter. Maybe, I'm a bit lazy when I build the SQL string. Should I always use SqlParameters? What are the advantages/disadvantages between building SQL string and using SqlParameter? Does...
7
2704
by: Steven Bethard | last post by:
I've updated PEP 359 with a bunch of the recent suggestions. The patch is available at: http://bugs.python.org/1472459 and I've pasted the full text below. I've tried to be more explicit about the goals -- the make statement is mostly syntactic sugar for:: class <name> <tuple>: __metaclass__ = <callable>
1
3043
by: javedna | last post by:
Can PHP help with the following as I have tried in the MYSQL Forums and cant get any help Thanks Nabz ---------------------------------------- Hi I am developing a PHP MYSQL questionnaire tool. The problem I am having is that of inserting all the answers into the table. The questionnaire is Dynamic so the number of questions can vary. I have a variable that counts them so at the moment there is 75 questions.
26
3238
by: a.mil | last post by:
I am programming for code-speed, not for ansi or other nice-guy stuff and I encountered the following problem: When I have a for loop like this: b=b0; for (a=0,i=0;i<100;i++,b--) { if (b%i) continue; a=1; }
18
7980
by: dspfun | last post by:
Hi! The words "expression" and "statement" are often used in C99 and C- textbooks, however, I am not sure of the clear defintion of these words with respect to C. Can somebody provide a sharp defintion of "expression" and "statement"? What is the difference between an expression and a statement?
23
2079
by: florian.loitsch | last post by:
According to the spec Section 14 the production SourceElements:SourceElements SourceElement is evaluated as follows: 1. Evaluate SourceElements. 2. If Result(1) is an abrupt completion, return Result(1) 3. Evaluate SourceElement. 4. Return Result(3). If I understood correctly the following program should alert 'undefined': alert(eval('3;;'));
21
17462
beacon
by: beacon | last post by:
Hello to everybody, I have a section on a form that has 10 questions, numbered 1-10, with 3 option buttons per question. Each of the option buttons have the same response (Yes, No, Don't know), but each answer is given a different point value for each question. For instance, question 1 might ask "Do you like candy?" and if you answer Yes you will get +1, No will earn you -1, and Don't know will net you zero points. The next question might...
10
3574
by: JohnO | last post by:
Hi All, This question is related to iSeries V5R4 and db2. I want to implement an AFTER DELETE trigger to save the deleted rows to an archive table, I initially defined it as a FOR EACH STATEMENT trigger that would insert all the deleted rows in one operation like this: CREATE TRIGGER MyTable_TD
0
9703
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9566
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10555
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9127
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7607
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6844
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5503
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5636
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3802
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.