473,508 Members | 2,489 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Particularly Challenging SQL Problem.

Table DDL:

create table test
(
inId int primary key identity,
inFK int not null,
inSeq int not null,
dtDate datetime
)

Data Insert:
insert into test
select 1,1, getdate()

WAITFOR DELAY '000:00:01'

insert into test
select 1,1, getdate()

WAITFOR DELAY '000:00:01'

insert into test
select 1,1, getdate()

WAITFOR DELAY '000:00:01'

insert into test
select 2,1, getdate()

WAITFOR DELAY '000:00:01'

insert into test
select 2,1, getdate()

WAITFOR DELAY '000:00:01'

insert into test
select 3,1, getdate()

WAITFOR DELAY '000:00:01'

insert into test
select 4,1, getdate()
If we select on this table:
inId inFK inSeq dtDate

----------- ----------- -----------
------------------------------------------------------
1 1 1 2005-02-01 12:54:40.967
2 1 1 2005-02-01 12:54:41.967
3 1 1 2005-02-01 12:54:42.967
4 2 1 2005-02-01 12:54:43.967
5 2 1 2005-02-01 12:54:44.967
6 3 1 2005-02-01 12:54:45.983
7 4 1 2005-02-01 12:54:47.077

(7 row(s) affected)
Problem:
What I would like to do (using SQL and not a cursor) is to update the
value of inSeq to its ordinal position, this will be based on the # of
occurences of inFK. For Example, I would like to run a sql statement
that would transform the data to:

update test
set inSEQ = (some sql)

select * from test - This would then produce:

inId inFK inSeq dtDate

----------- ----------- -----------
------------------------------------------------------
1 1 1 2005-02-01 12:54:40.967
2 1 2 2005-02-01 12:54:41.967
3 1 3 2005-02-01 12:54:42.967
4 2 1 2005-02-01 12:54:43.967
5 2 2 2005-02-01 12:54:44.967
6 3 1 2005-02-01 12:54:45.983
7 4 1 2005-02-01 12:54:47.077
(7 row(s) affected)
Any help would be greatly appreciated.

TFD

Jul 23 '05 #1
17 1622
SSK
Hi

The following solution will work if the inserted records (with
same inFK value ) are in sequential order only.

update test set inSeq = (inid - (select min(inid) from test b where
a.infk = b.infk ) + 1) from test a

Thanks
Ssk

If the Records are
LineVoltageHalogen wrote:
Table DDL:

create table test
(
inId int primary key identity,
inFK int not null,
inSeq int not null,
dtDate datetime
)

Data Insert:
insert into test
select 1,1, getdate()

WAITFOR DELAY '000:00:01'

insert into test
select 1,1, getdate()

WAITFOR DELAY '000:00:01'

insert into test
select 1,1, getdate()

WAITFOR DELAY '000:00:01'

insert into test
select 2,1, getdate()

WAITFOR DELAY '000:00:01'

insert into test
select 2,1, getdate()

WAITFOR DELAY '000:00:01'

insert into test
select 3,1, getdate()

WAITFOR DELAY '000:00:01'

insert into test
select 4,1, getdate()
If we select on this table:
inId inFK inSeq dtDate

----------- ----------- -----------
------------------------------------------------------
1 1 1 2005-02-01 12:54:40.967
2 1 1 2005-02-01 12:54:41.967
3 1 1 2005-02-01 12:54:42.967
4 2 1 2005-02-01 12:54:43.967
5 2 1 2005-02-01 12:54:44.967
6 3 1 2005-02-01 12:54:45.983
7 4 1 2005-02-01 12:54:47.077

(7 row(s) affected)
Problem:
What I would like to do (using SQL and not a cursor) is to update the
value of inSeq to its ordinal position, this will be based on the # of occurences of inFK. For Example, I would like to run a sql statement that would transform the data to:

update test
set inSEQ = (some sql)

select * from test - This would then produce:

inId inFK inSeq dtDate

----------- ----------- -----------
------------------------------------------------------
1 1 1 2005-02-01 12:54:40.967
2 1 2 2005-02-01 12:54:41.967
3 1 3 2005-02-01 12:54:42.967
4 2 1 2005-02-01 12:54:43.967
5 2 2 2005-02-01 12:54:44.967
6 3 1 2005-02-01 12:54:45.983
7 4 1 2005-02-01 12:54:47.077
(7 row(s) affected)
Any help would be greatly appreciated.

TFD


Jul 23 '05 #2
I can probably control this by creating a clusterd primary key on inId,
inFk, and sdDate, do you concur?

TFD

Jul 23 '05 #3
No. A clustered index is irrelevant. It has no impact on the standard,
documented behaviour of an UPDATE statement. The results of certain unusual
and ambiguous UPDATE statements which are undefined in the documentation may
be affected by indexes but the behaviour of those remains the same in each
case: the result is undefined and therefore unreliable.

If inseq is based purely on the values of infk and dtdate then there is no
obvious need to put the column in the table at all. Derive the sequence when
you query the table or add the numbering at client-side:

SELECT T1.inid, T1.infk,
COUNT(*) AS inseq, T1.dtdate
FROM Test AS T1
JOIN Test AS T2
ON T1.infk = T2.infk
AND T1.dtdate >= T2.dtdate
GROUP BY T1.inid, T1.infk, T1.dtdate

--
David Portas
SQL Server MVP
--
Jul 23 '05 #4
On 1 Feb 2005 09:58:01 -0800, LineVoltageHalogen wrote:

(snip)
Problem:
What I would like to do (using SQL and not a cursor) is to update the
value of inSeq to its ordinal position, this will be based on the # of
occurences of inFK. For Example, I would like to run a sql statement
that would transform the data to:

(snip)

Hi TFD,

Thanks for providing the create table and insert statements and the
expected output to clarify your need.

The following update statement will set the inSeq values as requested:

UPDATE test
SET inSeq = (SELECT COUNT(*)
FROM test AS t
WHERE t.inFK = test.inFK
AND t.dtDate <= test.dtDate)

By the way - using datatype-prefixes to column names is really not a
recommended practice. Would you really want to go over all your code if
the datatype of one of your columns has to be changed?

Best, Hugo
--

(Remove _NO_ and _SPAM_ to get my e-mail address)
Jul 23 '05 #5
David, thank you for your response. Doing stuff client side is not an
option for me, the example I put forth is just the gist of what I need
to do. I am actually implementing an ETL for a BI tool and this
example demonstrates the nature of the real problem I am solving. So,
an update statement is required, I also don't have the luxury of
knowing how many inFk,inSeq pairs will be coming in until after the
load completes. Can your query be modified to accomodate an update?
TFD

Jul 23 '05 #6
Hugo, if I understand correctly this query does not depend on the
physical order of the data on disk?

Jul 23 '05 #7
SQL statements never depend on the physical order of the data on disk.
That's a basic principle of an RDBMS.

Why do you ask?

--
David Portas
SQL Server MVP
--
Jul 23 '05 #8
I just want to understand, that is all. I was thinking that if they
had been sorted when I kicked off the update that SQL would just start
with the first record and then rip through them all from begining to
end. That would seem like the most natural action on SQL's part, how
else would it decide on the order in which is was going to execute the
update? Let's assume we have a simple query such as:

update table
set row = 'new value'

Wouldn't SQL just go to the head of the set and begin updating until it
reaches the end?

L

Jul 23 '05 #9
David Portas (RE****************************@acm.org) writes:
If inseq is based purely on the values of infk and dtdate then there is
no obvious need to put the column in the table at all. Derive the
sequence when you query the table or add the numbering at client-side:

SELECT T1.inid, T1.infk,
COUNT(*) AS inseq, T1.dtdate
FROM Test AS T1
JOIN Test AS T2
ON T1.infk = T2.infk
AND T1.dtdate >= T2.dtdate
GROUP BY T1.inid, T1.infk, T1.dtdate


The performance of this type of query is not always that fantastic, so
if you need the row numbering often, it may indeed be a good idea to
compute it once.
--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 23 '05 #10
The Relational Model and set-based SQL keep the logical results of a any
data manipulation abstracted from the way the data is physically stored. A
table is logically unordered and cannot be "sorted" but irrespective of the
order in which data is physically stored the result of any operation on the
data is the same. This principle is called Physical Data Independence. You
should read a book on relational basics.

--
David Portas
SQL Server MVP
--
Jul 23 '05 #11
David, again thank you for taking the time to inform me. I am quite
aware of Physical Independence and I would bet that the question I am
trying to ask probably won't be answered in a book on the basics of
theory. I am just curious how SQL actually handles this internally,
how it writes to disk, how it chooses an access path, etc. I know it
is not relevant to my problem but sometimes I like to visualize what is
going on at the physical implementation level.

Regards, TFD.

Jul 23 '05 #12
SQL Server's Query Optimizer chooses the access path to the data based on
analysis of indexes and statistics for your table(s). The Optimizer may
choose a different plan on different occassions, even for the same query and
table structure.

If you want to read more about SQL Server internals I recommend "Inside SQL
Server" by Kalen Delaney.

--
David Portas
SQL Server MVP
--
Jul 23 '05 #13
LineVoltageHalogen (tr****************@yahoo.com) writes:
David, again thank you for taking the time to inform me. I am quite
aware of Physical Independence and I would bet that the question I am
trying to ask probably won't be answered in a book on the basics of
theory. I am just curious how SQL actually handles this internally,
how it writes to disk, how it chooses an access path, etc. I know it
is not relevant to my problem but sometimes I like to visualize what is
going on at the physical implementation level.


The bottom line is that you cannot rely on physical ordering.

In 6.5 and previous version if you had a clustered index on a table
and said

SELECT * FROM tbl

you could be pretty sure that you would get the rows ordered according
to the clustered index. Same if you had an unindexed table, you would
get back the rows in the order they had been inserted.

But from SQL7 this is no longer true. This is because the SQL Server
engine has improved, and now can return data from multiple output
streams. If you have a somewhat large table with, say, 20000 rows, and
say SELECT * FRON tbl, you may contiguous blocks of ids, but there
will be some random variation of the blocks.
--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 23 '05 #14
On 1 Feb 2005 14:22:13 -0800, LineVoltageHalogen wrote:
I just want to understand, that is all. I was thinking that if they
had been sorted when I kicked off the update that SQL would just start
with the first record and then rip through them all from begining to
end.
Hi L,

In theory, an UPDATE statement is carried out instantaneously. One moment,
all rows have the "old" value; the next moment, all rows are changed to
the "new" value.

In practice, nothing can be done instantaneously. The computer needs some
time to fetch data from disk or cache, calculate the new values, push the
new values back to the cache and write the log entries to disk. Depending
on table size, available indexes, workload and lots of other factors, your
UPDATE statement will take anything from microseconds to hours or even
more.

During the time the UPDATE statement is processing, the number of changed
rows will be gradually increasing. Each changed row is also locked - this
means that no other process will get access to the data. All these locks
are held until the entire transaction is finished.

What happens if you fire a long-running UPDATE, then try to read some rows
from another connection? Well, there are basically two possibilities:
either the row you read has not yet been affected by the UPDATE - in that
case, you'll get to see the "old" value. But if the row has already been
changed by the UPDATE, you'll see nothing - the execution of your query is
postponed until the lock on the required row is lifted. Once the UPDATE is
completely done, the required row can be read, and you'll get the new data
returned.

The net effect of this is, that until the UPDATE statement has finished,
other people can't ever see the new data - either they see the old data,
or they are "put on hold" (blocked). After the UPDATE statement has
finished, other people will only see the new data. So even though the
UPDATE can't really be carried out instanteneously, the combination of
locking and blocking ensures that the system behaves as if it is.
That would seem like the most natural action on SQL's part, how
else would it decide on the order in which is was going to execute the
update? Let's assume we have a simple query such as:

update table
set row = 'new value'

Wouldn't SQL just go to the head of the set and begin updating until it
reaches the end?


SQL Server is entirely free to choose it's own strategy for carrying out
the update. The chosen order might depend on many factors, like indexes
available, workload, table statistics or maybe even the weather - but
since the system behaves as if all rows were affected at the same time, it
really doesn't matter what order SQL Server picks.

Best, Hugo
--

(Remove _NO_ and _SPAM_ to get my e-mail address)
Jul 23 '05 #15
Understood. Thank You.

Jul 23 '05 #16
Excellent information. Thank you very much. This is exactly what I
was looking for.

TFD

Jul 23 '05 #17
>> Let's assume we have a simple query such as:
update table
set row = 'new value'
Wouldn't SQL just go to the head of the set and begin updati*ng until
it reaches the end? <<

No! And the phrase "head of the set" and "end" make absolutley no
sense. Sets have no ordering. This is high school math, not
programming.

SQL is a set-oriented language. The UPDATE has to act as if it follows
these steps:
1) Mark all the rows that qualify in the WHERE clause
2) Construct a new image of the set of rows to be modified
3) Delete the old rows as a set
4) Insert the new rows as a set
5) Do a commit or rollback as needed

This is parallel behavior, not sequential file behavior. For example,

UPDATE Foobar
SET a=b, b=a;

will swap the the values of a and b because the entire new row is
constructed at once as an element of a set. In a sequential file
system you would the assignments left to right and both columns (fields
in a file system) would get the value of b.

Jul 23 '05 #18

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

Similar topics

0
2141
by: Philip Meyer | last post by:
1) setting image as Background with alignment in center not working..help Explanation : i need to set a image as background and also it should be dispalyed in the center.i am using apache fop...
3
1266
by: Kent | last post by:
The following is a greatly simplified example of what I would like to accomplish using the event/delegate features of .NET I have a class "NumGen" that produces a random set of numbers between 0...
11
1401
by: George | last post by:
Was my question too challenging for everyone? I thought I would get a much quicker response, complete with witty and (sometimes) condescending remarks Here's my question again, in case you missed...
3
1179
by: ramata | last post by:
I am woring on a project that involves a common but quite challanging and complex problem. I describe the scenario with a common example. School Attendence website: The school maintains records...
18
1553
by: Frankie | last post by:
I have been hired to go to a former client of mine and train their staff programmers on ASP.NET. These guys have only Mainframe, MS Access, SQL Server, and VB6 desktop application development...
2
1338
by: Wayne | last post by:
This is a copy of a message I previously posted in a Microsoft Access Newsgroup, but it was suggested to me that my problem is ASP related and not Access, and hence I'm posting in this newsgroup now...
10
1257
by: exekutive | last post by:
I've been wrestling with this programming problem for some time now, so I thought I'd put it up for discussion. I'm trying to design a Mask function. See if you can figure out a code for it... ...
5
1220
by: alainpoint | last post by:
Hi, I have what in my eyes seems a challenging problem. Thanks to Peter Otten, i got the following code to work. It is a sort of named tuple. from operator import itemgetter def...
2
1037
by: Hisouka | last post by:
DBase = 'MYDB' User = 'Hisouka' Password = '1234' HEre is my Table in SQL Server Tablename: TABLESAMP
0
7231
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,...
0
7133
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...
0
7336
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,...
0
7405
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7066
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5643
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,...
0
4724
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...
0
3198
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1568
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

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.