Welcome to dbFreaks.com!
FAQFAQ    SearchSearch      ProfileProfile    Private MessagesPrivate Messages   Log inLog in

select rowcount per group before value in group = null

 
   Database Help (Home) -> Programming RSS
Next:  how to use SUM  
Author Message
Rich

External


Since: Feb 07, 2008
Posts: 112



(Msg. 1) Posted: Tue Jul 22, 2008 8:38 am
Post subject: select rowcount per group before value in group = null
Archived from groups: microsoft>public>sqlserver>programming (more info?)

I need to select the top 3 rows per each group (xID -- order by xID). No
problem here. But I need to select the count of rows in each group before a
null value is encountered in the stat column -- ordering by xID

CREATE TABLE #tmp1(rowID int Identity(1,1), xID int, x1 int, stat varchar(1))

INSERT INTO #tmp1
SELECT 1, 1, 'f'
UNION ALL SELECT 1, 2, 'f'
UNION ALL SELECT 1, 3, 'f'
UNION ALL SELECT 1, 4, 'f'
UNION ALL SELECT 2, 1, 'f'
UNION ALL SELECT 2, 2, null
UNION ALL SELECT 2, 3, 'f'
UNION ALL SELECT 2, 4, 'f'
UNION ALL SELECT 3, 1, 'f'
UNION ALL SELECT 3, 2, 'f'
UNION ALL SELECT 3, 3, null

Here is what I have for getting the top 3 rows per group:

SELECT * FROM #tmp1 t1 WHERE EXISTS
(SELECT * FROM (SELECT TOP 3 * FROM #tmp1 t2 WHERE t2.xId = t1.xId ORDER BY
t2.xid) t3 WHERE t3.rowID = t1.rowID). This returns:


rowID xID x1 stat
1 1 1 f
2 1 2 f
3 1 3 f
5 2 1 f
6 2 2 NULL
7 2 3 f
9 3 1 f
10 3 2 f
11 3 3 NULL

From here I need to get this output

xID rowcount stat
1 3 f
2 1 f
3 2 f

xID = 1 had 3 rows (no null values encountered)
xID = 2 had 1 row before encountering a null
xID = 3 had 2 rows before encountering a null

Is it possible to get this output from the source data without looping?

Thanks,
Rich

 >> Stay informed about: select rowcount per group before value in group = null 
Back to top
Login to vote
"Roy Harvey

External


Since: Jan 12, 2008
Posts: 593



(Msg. 2) Posted: Tue Jul 22, 2008 12:25 pm
Post subject: Re: select rowcount per group before value in group = null [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

SELECT A.xID, MAX(A.rownum), A.stat
FROM (SELECT *,
row_number() over (PARTITION BY xID
ORDER BY xID, rowID) as rownum
FROM #tmp1) as A
JOIN (SELECT *,
row_number() over (PARTITION BY xID
ORDER BY xID, rowID) as rownum
FROM #tmp1
WHERE stat IS NOT NULL) as B
ON A.rowID = B.rowID
AND A.rownum = B.rownum
WHERE A.rownum <= 3
GROUP BY A.xid, A.stat

xID stat
----------- -------------------- ----
1 3 f
2 1 f
3 2 f

The idea is that we number the rows once including the NULLs, and once
without the NULLs, and only take the ones where the numbers match.

Roy Harvey
Beacon Falls, CT


On Tue, 22 Jul 2008 08:38:01 -0700, Rich
wrote:

>I need to select the top 3 rows per each group (xID -- order by xID). No
>problem here. But I need to select the count of rows in each group before a
>null value is encountered in the stat column -- ordering by xID
>
>CREATE TABLE #tmp1(rowID int Identity(1,1), xID int, x1 int, stat varchar(1))
>
>INSERT INTO #tmp1
>SELECT 1, 1, 'f'
>UNION ALL SELECT 1, 2, 'f'
>UNION ALL SELECT 1, 3, 'f'
>UNION ALL SELECT 1, 4, 'f'
>UNION ALL SELECT 2, 1, 'f'
>UNION ALL SELECT 2, 2, null
>UNION ALL SELECT 2, 3, 'f'
>UNION ALL SELECT 2, 4, 'f'
>UNION ALL SELECT 3, 1, 'f'
>UNION ALL SELECT 3, 2, 'f'
>UNION ALL SELECT 3, 3, null
>
>Here is what I have for getting the top 3 rows per group:
>
>SELECT * FROM #tmp1 t1 WHERE EXISTS
>(SELECT * FROM (SELECT TOP 3 * FROM #tmp1 t2 WHERE t2.xId = t1.xId ORDER BY
>t2.xid) t3 WHERE t3.rowID = t1.rowID). This returns:
>
>
>rowID xID x1 stat
>1 1 1 f
>2 1 2 f
>3 1 3 f
>5 2 1 f
>6 2 2 NULL
>7 2 3 f
>9 3 1 f
>10 3 2 f
>11 3 3 NULL
>
>From here I need to get this output
>
>xID rowcount stat
>1 3 f
>2 1 f
>3 2 f
>
>xID = 1 had 3 rows (no null values encountered)
>xID = 2 had 1 row before encountering a null
>xID = 3 had 2 rows before encountering a null
>
>Is it possible to get this output from the source data without looping?
>
>Thanks,
>Rich

 >> Stay informed about: select rowcount per group before value in group = null 
Back to top
Login to vote
Rich

External


Since: Feb 07, 2008
Posts: 112



(Msg. 3) Posted: Tue Jul 22, 2008 12:25 pm
Post subject: Re: select rowcount per group before value in group = null [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Thank you for your reply. I forgot to mention that we are still on sql 2000
over at my place (man, we need to upgrade!). I was just reading an article
about the Row_Number function for sql 2005. I will try to translate that
back to sql 2000 - which I understand will require the use of a #tmp table
(or 2). In the meantime, can I translate the query below in one continuous
statement? Or will I have to actually create a separate #tmp table first to
make it useable for sql 2000?


"Roy Harvey (SQL Server MVP)" wrote:

> SELECT A.xID, MAX(A.rownum), A.stat
> FROM (SELECT *,
> row_number() over (PARTITION BY xID
> ORDER BY xID, rowID) as rownum
> FROM #tmp1) as A
> JOIN (SELECT *,
> row_number() over (PARTITION BY xID
> ORDER BY xID, rowID) as rownum
> FROM #tmp1
> WHERE stat IS NOT NULL) as B
> ON A.rowID = B.rowID
> AND A.rownum = B.rownum
> WHERE A.rownum <= 3
> GROUP BY A.xid, A.stat
>
> xID stat
> ----------- -------------------- ----
> 1 3 f
> 2 1 f
> 3 2 f
>
> The idea is that we number the rows once including the NULLs, and once
> without the NULLs, and only take the ones where the numbers match.
>
> Roy Harvey
> Beacon Falls, CT
>
>
> On Tue, 22 Jul 2008 08:38:01 -0700, Rich
> wrote:
>
> >I need to select the top 3 rows per each group (xID -- order by xID). No
> >problem here. But I need to select the count of rows in each group before a
> >null value is encountered in the stat column -- ordering by xID
> >
> >CREATE TABLE #tmp1(rowID int Identity(1,1), xID int, x1 int, stat varchar(1))
> >
> >INSERT INTO #tmp1
> >SELECT 1, 1, 'f'
> >UNION ALL SELECT 1, 2, 'f'
> >UNION ALL SELECT 1, 3, 'f'
> >UNION ALL SELECT 1, 4, 'f'
> >UNION ALL SELECT 2, 1, 'f'
> >UNION ALL SELECT 2, 2, null
> >UNION ALL SELECT 2, 3, 'f'
> >UNION ALL SELECT 2, 4, 'f'
> >UNION ALL SELECT 3, 1, 'f'
> >UNION ALL SELECT 3, 2, 'f'
> >UNION ALL SELECT 3, 3, null
> >
> >Here is what I have for getting the top 3 rows per group:
> >
> >SELECT * FROM #tmp1 t1 WHERE EXISTS
> >(SELECT * FROM (SELECT TOP 3 * FROM #tmp1 t2 WHERE t2.xId = t1.xId ORDER BY
> >t2.xid) t3 WHERE t3.rowID = t1.rowID). This returns:
> >
> >
> >rowID xID x1 stat
> >1 1 1 f
> >2 1 2 f
> >3 1 3 f
> >5 2 1 f
> >6 2 2 NULL
> >7 2 3 f
> >9 3 1 f
> >10 3 2 f
> >11 3 3 NULL
> >
> >From here I need to get this output
> >
> >xID rowcount stat
> >1 3 f
> >2 1 f
> >3 2 f
> >
> >xID = 1 had 3 rows (no null values encountered)
> >xID = 2 had 1 row before encountering a null
> >xID = 3 had 2 rows before encountering a null
> >
> >Is it possible to get this output from the source data without looping?
> >
> >Thanks,
> >Rich
>
 >> Stay informed about: select rowcount per group before value in group = null 
Back to top
Login to vote
Tom Cooper

External


Since: Jan 10, 2008
Posts: 463



(Msg. 4) Posted: Tue Jul 22, 2008 12:53 pm
Post subject: Re: select rowcount per group before value in group = null [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

One way to do it in SQL 2000,

SELECT t1.xId, Count(*) As 'rowcount', t1.stat FROM #tmp1 t1 WHERE EXISTS
(SELECT * FROM (SELECT TOP 3 * FROM #tmp1 t2
WHERE t2.xId = t1.xId ORDER BY
t2.xid) t3 WHERE t3.rowID = t1.rowID
AND NOT EXISTS (SELECT * FROM #tmp1 t4 WHERE t3.xID = t4.xID
And t3.RowId >= t4.RowId And t4.stat Is Null))
Group By t1.xId, t1.stat
Order By t1.xId, t1.stat

Note that if you have a large amount of data, a cursor might execute faster.

Tom

"Rich" wrote in message

> Thank you for your reply. I forgot to mention that we are still on sql
> 2000
> over at my place (man, we need to upgrade!). I was just reading an
> article
> about the Row_Number function for sql 2005. I will try to translate that
> back to sql 2000 - which I understand will require the use of a #tmp table
> (or 2). In the meantime, can I translate the query below in one
> continuous
> statement? Or will I have to actually create a separate #tmp table first
> to
> make it useable for sql 2000?
>
>
> "Roy Harvey (SQL Server MVP)" wrote:
>
>> SELECT A.xID, MAX(A.rownum), A.stat
>> FROM (SELECT *,
>> row_number() over (PARTITION BY xID
>> ORDER BY xID, rowID) as rownum
>> FROM #tmp1) as A
>> JOIN (SELECT *,
>> row_number() over (PARTITION BY xID
>> ORDER BY xID, rowID) as rownum
>> FROM #tmp1
>> WHERE stat IS NOT NULL) as B
>> ON A.rowID = B.rowID
>> AND A.rownum = B.rownum
>> WHERE A.rownum <= 3
>> GROUP BY A.xid, A.stat
>>
>> xID stat
>> ----------- -------------------- ----
>> 1 3 f
>> 2 1 f
>> 3 2 f
>>
>> The idea is that we number the rows once including the NULLs, and once
>> without the NULLs, and only take the ones where the numbers match.
>>
>> Roy Harvey
>> Beacon Falls, CT
>>
>>
>> On Tue, 22 Jul 2008 08:38:01 -0700, Rich
>> wrote:
>>
>> >I need to select the top 3 rows per each group (xID -- order by xID).
>> >No
>> >problem here. But I need to select the count of rows in each group
>> >before a
>> >null value is encountered in the stat column -- ordering by xID
>> >
>> >CREATE TABLE #tmp1(rowID int Identity(1,1), xID int, x1 int, stat
>> >varchar(1))
>> >
>> >INSERT INTO #tmp1
>> >SELECT 1, 1, 'f'
>> >UNION ALL SELECT 1, 2, 'f'
>> >UNION ALL SELECT 1, 3, 'f'
>> >UNION ALL SELECT 1, 4, 'f'
>> >UNION ALL SELECT 2, 1, 'f'
>> >UNION ALL SELECT 2, 2, null
>> >UNION ALL SELECT 2, 3, 'f'
>> >UNION ALL SELECT 2, 4, 'f'
>> >UNION ALL SELECT 3, 1, 'f'
>> >UNION ALL SELECT 3, 2, 'f'
>> >UNION ALL SELECT 3, 3, null
>> >
>> >Here is what I have for getting the top 3 rows per group:
>> >
>> >SELECT * FROM #tmp1 t1 WHERE EXISTS
>> >(SELECT * FROM (SELECT TOP 3 * FROM #tmp1 t2 WHERE t2.xId = t1.xId ORDER
>> >BY
>> >t2.xid) t3 WHERE t3.rowID = t1.rowID). This returns:
>> >
>> >
>> >rowID xID x1 stat
>> >1 1 1 f
>> >2 1 2 f
>> >3 1 3 f
>> >5 2 1 f
>> >6 2 2 NULL
>> >7 2 3 f
>> >9 3 1 f
>> >10 3 2 f
>> >11 3 3 NULL
>> >
>> >From here I need to get this output
>> >
>> >xID rowcount stat
>> >1 3 f
>> >2 1 f
>> >3 2 f
>> >
>> >xID = 1 had 3 rows (no null values encountered)
>> >xID = 2 had 1 row before encountering a null
>> >xID = 3 had 2 rows before encountering a null
>> >
>> >Is it possible to get this output from the source data without looping?
>> >
>> >Thanks,
>> >Rich
>>
 >> Stay informed about: select rowcount per group before value in group = null 
Back to top
Login to vote
Rich

External


Since: Feb 07, 2008
Posts: 112



(Msg. 5) Posted: Tue Jul 22, 2008 12:53 pm
Post subject: Re: select rowcount per group before value in group = null [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

Thank you for your reply. Question: I am sure a cursor would be faster for
large data than to query large data using Exists - But would the query using
the Row_Number function (sql 2005 query) be more efficient than the cursor
(and using Exists) ? Or for this case (using large data) would the cursor be
the most efficient solution?



"Tom Cooper" wrote:

> One way to do it in SQL 2000,
>
> SELECT t1.xId, Count(*) As 'rowcount', t1.stat FROM #tmp1 t1 WHERE EXISTS
> (SELECT * FROM (SELECT TOP 3 * FROM #tmp1 t2
> WHERE t2.xId = t1.xId ORDER BY
> t2.xid) t3 WHERE t3.rowID = t1.rowID
> AND NOT EXISTS (SELECT * FROM #tmp1 t4 WHERE t3.xID = t4.xID
> And t3.RowId >= t4.RowId And t4.stat Is Null))
> Group By t1.xId, t1.stat
> Order By t1.xId, t1.stat
>
> Note that if you have a large amount of data, a cursor might execute faster.
>
> Tom
>
> "Rich" wrote in message
>
> > Thank you for your reply. I forgot to mention that we are still on sql
> > 2000
> > over at my place (man, we need to upgrade!). I was just reading an
> > article
> > about the Row_Number function for sql 2005. I will try to translate that
> > back to sql 2000 - which I understand will require the use of a #tmp table
> > (or 2). In the meantime, can I translate the query below in one
> > continuous
> > statement? Or will I have to actually create a separate #tmp table first
> > to
> > make it useable for sql 2000?
> >
> >
> > "Roy Harvey (SQL Server MVP)" wrote:
> >
> >> SELECT A.xID, MAX(A.rownum), A.stat
> >> FROM (SELECT *,
> >> row_number() over (PARTITION BY xID
> >> ORDER BY xID, rowID) as rownum
> >> FROM #tmp1) as A
> >> JOIN (SELECT *,
> >> row_number() over (PARTITION BY xID
> >> ORDER BY xID, rowID) as rownum
> >> FROM #tmp1
> >> WHERE stat IS NOT NULL) as B
> >> ON A.rowID = B.rowID
> >> AND A.rownum = B.rownum
> >> WHERE A.rownum <= 3
> >> GROUP BY A.xid, A.stat
> >>
> >> xID stat
> >> ----------- -------------------- ----
> >> 1 3 f
> >> 2 1 f
> >> 3 2 f
> >>
> >> The idea is that we number the rows once including the NULLs, and once
> >> without the NULLs, and only take the ones where the numbers match.
> >>
> >> Roy Harvey
> >> Beacon Falls, CT
> >>
> >>
> >> On Tue, 22 Jul 2008 08:38:01 -0700, Rich
> >> wrote:
> >>
> >> >I need to select the top 3 rows per each group (xID -- order by xID).
> >> >No
> >> >problem here. But I need to select the count of rows in each group
> >> >before a
> >> >null value is encountered in the stat column -- ordering by xID
> >> >
> >> >CREATE TABLE #tmp1(rowID int Identity(1,1), xID int, x1 int, stat
> >> >varchar(1))
> >> >
> >> >INSERT INTO #tmp1
> >> >SELECT 1, 1, 'f'
> >> >UNION ALL SELECT 1, 2, 'f'
> >> >UNION ALL SELECT 1, 3, 'f'
> >> >UNION ALL SELECT 1, 4, 'f'
> >> >UNION ALL SELECT 2, 1, 'f'
> >> >UNION ALL SELECT 2, 2, null
> >> >UNION ALL SELECT 2, 3, 'f'
> >> >UNION ALL SELECT 2, 4, 'f'
> >> >UNION ALL SELECT 3, 1, 'f'
> >> >UNION ALL SELECT 3, 2, 'f'
> >> >UNION ALL SELECT 3, 3, null
> >> >
> >> >Here is what I have for getting the top 3 rows per group:
> >> >
> >> >SELECT * FROM #tmp1 t1 WHERE EXISTS
> >> >(SELECT * FROM (SELECT TOP 3 * FROM #tmp1 t2 WHERE t2.xId = t1.xId ORDER
> >> >BY
> >> >t2.xid) t3 WHERE t3.rowID = t1.rowID). This returns:
> >> >
> >> >
> >> >rowID xID x1 stat
> >> >1 1 1 f
> >> >2 1 2 f
> >> >3 1 3 f
> >> >5 2 1 f
> >> >6 2 2 NULL
> >> >7 2 3 f
> >> >9 3 1 f
> >> >10 3 2 f
> >> >11 3 3 NULL
> >> >
> >> >From here I need to get this output
> >> >
> >> >xID rowcount stat
> >> >1 3 f
> >> >2 1 f
> >> >3 2 f
> >> >
> >> >xID = 1 had 3 rows (no null values encountered)
> >> >xID = 2 had 1 row before encountering a null
> >> >xID = 3 had 2 rows before encountering a null
> >> >
> >> >Is it possible to get this output from the source data without looping?
> >> >
> >> >Thanks,
> >> >Rich
> >>
>
>
>
 >> Stay informed about: select rowcount per group before value in group = null 
Back to top
Login to vote
"Roy Harvey

External


Since: Jan 12, 2008
Posts: 593



(Msg. 6) Posted: Tue Jul 22, 2008 1:30 pm
Post subject: Re: select rowcount per group before value in group = null [Login to view extended thread Info.]
Archived from groups: per prev. post (more info?)

On Tue, 22 Jul 2008 10:20:01 -0700, Rich
wrote:

> I am sure a cursor would be faster for
>large data than to query large data using Exists

Don't be. With good indexing the answer will usually go the other
way.

Roy Harvey
Beacon Falls, CT
 >> Stay informed about: select rowcount per group before value in group = null 
Back to top
Login to vote
Display posts from previous:   
Related Topics:
group by + rowcount - I have a simple query with group by. and I want to get the topX rows from each group. how to do that ? for example declare @myTable table ( id int identity(1,1), <font color=brown> ; ; ; comment int,</font> <fon...

select/isolate group from... where max(date in group) = so.. - In the following data I need to select (or isolate) the codes (code groups) which contain a max codeDate of '12/31/08'. Of the codes a, b, c, d -- only codes b and c contain a max codeDate of '12/31/08' in their respective groups. What would be the...

Select RowCount Update RowCount - Thanks in advance for any assistance. I'm running a query that returns 207 rows to be updated, however the update statement only updates 205 rows? I've disabled the trigger on the target table, but that made no difference. Thanks, Morgan This query..

SELECT GROUP BY smalltimedate - Hi, I have an access query that I need to convert to Sql Server. It looks like: "SELECT Top 20 Count(MessageID) AS CountOfMessages, DateValue(datestamp) AS Expr1 From Messages GROUP BY DateValue (datestamp) ORDER BY DateValue(datestamp) DESC;&quo...

Using a datetime value in a select by group by the month - Hi, I have a table with sales data, and each transaction is dated, into a datetime field that is populated with the time of sale. What I want to do though is group all sales for reporting, but where I show the total for by months. How do i select al...
   Database Help (Home) -> Programming All times are: Pacific Time (US & Canada)
Page 1 of 1

 
You can post new topics in this forum
You can reply to topics in this forum
You can edit your posts in this forum
You can delete your posts in this forum
You can vote in polls in this forum



[ Contact us | Terms of Service/Privacy Policy ]