10

I have some data like this but more than 1500000 records and more than 700 users:

usercolumn   ,       datecolumn\     
a1            ,      1998/2/11\
a2            ,      1998/3/11\
a1            ,      1998/2/15\
a4            ,      1998/4/14\
a3            ,      1999/1/15\
a2            ,      1998/11/12\
a2            ,      1999/2/11\
a3            ,      2000/2/9\
a1            ,      1998/6/5\
a3            ,      1998/7/7\
a1            ,      1998/3/11\
a5            ,      1998/3/18\
a2            ,      1998/2/8\
a1            ,      1998/12/11\
a4            ,      1998/12/1\
a5            ,      1998/2/11\
....

I would like to have distinct data from usercolumn and minimum value of date for each user like this:

usercolumn      ,    datecolumn \        
a1              ,    1998/2/11\
a2              ,    1998/2/8\
a3              ,    1998/7/7\
a4              ,    1998/4/14\
a5              ,    1998/2/11\
....

please help me to write an SQL command to do this for oledb adapter in c#, thanks.

gbn
  • 422,506
  • 82
  • 585
  • 676
  • @dmitri's answer (once fixed as per my comment) is fine for the problem you state, but I suspect you mis-stated the problem: specifically, if you have other columns, you need another approach. – Alex Martelli Jun 20 '09 at 16:46

6 Answers6

30
SELECT usercolumn, MIN(datecolumn) FROM tablename GROUP BY usercolumn;

Note that if you want other columns they must either appear in the GROUP BY clause or be constant across rows. Otherwise the result will be non-deterministic.

David Murdoch
  • 87,823
  • 39
  • 148
  • 191
brian-brazil
  • 31,678
  • 6
  • 93
  • 86
2

This will work for SQLServer 2008 and DB2:

with temp as (
    select *, row_number() over (partition by usercolumn order by datecolumn) as rownum
    from table)
select * from temp 
where rownum = 1

It will give proper results even if you need to include multiple columns in the select.

Rashmi Pandit
  • 23,230
  • 17
  • 71
  • 111
0

Something like this should do the tick

    SELECT usercolumn
         , MIN(datecolumn)
      FROM YouTable
     GROUP BY usercolumn
         , MIN(datecolumn)
Dmitri Kouminov
  • 593
  • 2
  • 6
  • 12
  • 2
    "SQL error: aggregate functions are not allowed in the GROUP BY clause" (at least from decent SQL engines!-). Just remove the last line, grouping by min(datecolumn) makes no sense and the answer is fine without it anyway!-) – Alex Martelli Jun 20 '09 at 16:45
0

If you have more than just those two columns, the best SQL to use depends a bit on what server you have at the other end of that OleDB adapter, but here's something that will work well with many (alas, not all!) such possible servers:

SELECT t.*
FROM thetable t
LEFT JOIN thetable taux
  ON(t.usercolumn=taux.usercolumn
     AND t.datecolumn>taux.datecolumn)
WHERE taux.usecolumn IS NULL

which you could read as "emit those rows of thetable such that there is no other row of the table with the same user and a strictly-less date". If minimum date for a given user can occur multiple times this will give as many rows for that user -- if that's a problem for you, there are solutions to it, too... but I'll wait for you to clarify your question more before I work any more on this!-)

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
0

you could try this:

SELECT DISTINCT a.username, a.date
FROM tablename AS a INNER JOIN tablename AS b
ON(a.username = b.username AND a.date < b.date)

As for C#, cant help you there

mrt181
  • 5,080
  • 8
  • 66
  • 86
0

SELECT DISTINCT USERNAME, DATE FROM TABLENAME AS A WHERE A.DATE=(SELECT MIN(DATE) FROM TABLENAME WHERE USERNAME=A.USERNAME)