Unix Technical Forum

Particularly Challenging SQL Problem.

This is a discussion on Particularly Challenging SQL Problem. within the SQL Server forums, part of the Microsoft SQL Server category; --> Table DDL: create table test ( inId int primary key identity, inFK int not null, inSeq int not null, ...


Go Back   Unix Technical Forum > Database Server Software > Microsoft SQL Server > SQL Server

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-29-2008, 06:54 AM
LineVoltageHalogen
 
Posts: n/a
Default 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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 02-29-2008, 06:54 AM
SSK
 
Posts: n/a
Default Re: Particularly Challenging SQL Problem.

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


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 02-29-2008, 06:54 AM
LineVoltageHalogen
 
Posts: n/a
Default Re: Particularly Challenging SQL Problem.

I can probably control this by creating a clusterd primary key on inId,
inFk, and sdDate, do you concur?

TFD

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 02-29-2008, 06:54 AM
David Portas
 
Posts: n/a
Default Re: Particularly Challenging SQL Problem.

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
--


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 02-29-2008, 06:54 AM
Hugo Kornelis
 
Posts: n/a
Default Re: Particularly Challenging SQL Problem.

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)
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 02-29-2008, 06:54 AM
LineVoltageHalogen
 
Posts: n/a
Default Re: Particularly Challenging SQL Problem.

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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #7 (permalink)  
Old 02-29-2008, 06:54 AM
LineVoltageHalogen
 
Posts: n/a
Default Re: Particularly Challenging SQL Problem.

Hugo, if I understand correctly this query does not depend on the
physical order of the data on disk?

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #8 (permalink)  
Old 02-29-2008, 06:54 AM
David Portas
 
Posts: n/a
Default Re: Particularly Challenging SQL Problem.

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
--


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #9 (permalink)  
Old 02-29-2008, 06:54 AM
LineVoltageHalogen
 
Posts: n/a
Default Re: Particularly Challenging SQL Problem.

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

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #10 (permalink)  
Old 02-29-2008, 06:54 AM
Erland Sommarskog
 
Posts: n/a
Default Re: Particularly Challenging SQL Problem.

David Portas (REMOVE_BEFORE_REPLYING_dportas@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, esquel@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
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 10:40 AM.


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