views:

972

answers:

5

SQL Server 2000

My Table:

CARDNO  CARDEVENTDATE CARDEVENTTIME
121 20090610 025050
 121    20090611 040000
121 20090611 050000
121 20090611 020000
122 20090611 030001
122 20090611 030000
123 20090611 080000
123 20090611 100000
123 20090611 132449
123 20090611 025959
124 20090610 030000
124 20090612 030001
125 20090611 030002
125 20090612 040000

Cardno is Separate Table Cardeventdate, cardeventtime is separate table

From the above table I want to get Top Time and Bottom Time for the Particular cardeventdate and Cardno

For the 121, 20090611, Top Time is 040000, Bottom Time is 020000 For 123, 20090611, Top Time is 080000, Bottom Time is 025959 … Like this I need.

I used Min (time) and Max (time), But it showing like this.

For CardNo – 121 Cardeventdate – 20090611 Min Time – 020000 Max Time – 040000

I don’t want to get min and Max, I need only top and Bottom (or) First and Last time value of the particular Date and Cardno.

I used this Query

SELECT     RowNumber = IDENTITY (int, 1, 1), CARDNO, CARDEVENTDATE, CARDEVENTTIME INTO #Table1 FROM T_CARDEVENT SELECT     t1.CARDNO, t1.CARDEVENTDATE, t1.CARDEVENTTIME  FROM #Table t1 INNER JOIN (SELECT     RowNumber = MIN(RowNumber), CARDEVENTDATE, CARDNO  FROM  #Table1 t  WHERE      (cardeventdate > 20090601) GROUP BY cardno, cardeventdate  UNION ALL  SELECT     MAX(RowNumber), CARDEVENTDATE, CARDNO FROM #Table1 t WHERE     (cardeventdate > 20090601) GROUP BY cardno, cardeventdate) t2 ON t2.rownumber = t1.rownumber

Output:

ROWNUMBER   CARDNO CARDEVENTDATE CARDEVENTTIME
335 0121            20090611     040000
1099    0121            20090611     050000
1100    0121            20090611     025050
336 0121            20090612     020000
337 0122            20090611     030001
338 0122            20090612     030000
339 0123            20090611     080000
1101    0123            20090611     100000
1102    0123            20090611     132449
340 0123            20090612     025959
341 0124            20090611     030000
342 0124            20090612     030001
343 0125            20090611     030002
344 0125            20090612     040000

So Here Row Number is created for all columns, from that how I have to take First Time and Last Time for the Particular Date.

Expecting Output

CARDNO  CARDEVENTDATE CARDEVENTTIME Expecting
0121    20090611 040000 Top Value
0121    20090611 020000 No Need
0121    20090611 025050 Bottom Value

……… so on

Need Query Help.

+5  A: 

Well, unless you have some additional fields to establish an order, this is non deterministic. Given the three values for the 23-04-2009 - how is it that APPLE is the first and ROSE is the last? If the ID and the DATE are the same for all three entries, there's no order defined to filter out "GRAPHE"......

Marc

UPDATE: I expanded on Lieven's idea a bit and got this working in my setup:

DECLARE @TempTable TABLE (RowNumber INT IDENTITY(1,1), 
                          DayNumber INT, 
                          ID VARCHAR(3), DateField DATETIME, Value VARCHAR(32))

INSERT INTO @TempTable(DayNumber, id, datefield, value)
    SELECT DATEPART(DAYOFYEAR, DateField), ID, DateField, Value
    FROM @Table

SELECT * 
FROM @TempTable t
INNER JOIN 
   (SELECT RowNumber = MIN(RowNumber), DayNumber, ID
    FROM @TempTable t
    GROUP BY DayNumber, t.ID
    UNION ALL 
    SELECT MAX(RowNumber), DayNumber, ID
    FROM @TempTable t
    GROUP BY DayNumber, t.ID) t2 
  ON t2.RowNumber = t.RowNumber
GO

I'm basically creating a temp table with additional info - an artificial "RowNumber" to create some order, and the "DayNumber" to get dates grouped by date only (without time).

Seems to work ok for me - does it work for you, too?

marc_s
Agreed and for this reason the table isn't even in 1NF.
onedaywhen
+1 for the non deterministic observation.
Lieven
A: 

I havn't tried it, but maybe something like this might do it:

SELECT TOP(1) FROM Table
WHERE Date='Some-date'
AND Id=Some-Id
ORDER BY Date ASC
UNION
SELECT TOP(1) FROM Table
WHERE Date='Some-date'
AND Id=Some-Id
ORDER BY Date Desc
James Allen
Id - 001 to n, date - select this date to this dateFor this condition, how can i make a query
A: 

to cheat you can add an autonumber feild AUtoID ID DATE VALUE 1 001 23:04:2009 APPLE 2 001 23:04:2009 GRAPHE 3 001 23:04:2009 ROSE 4 001 24:04:2009 BERRY 5 001 24:04:2009 TIFFANY 6 001 24:04:2009 ORGANE 7 001 24:04:2009 SILVER

You can then do min and max against it

I usually use insert into a tempory table which is defined with the ID, technically the insertion order isn't garenteed going in.

Rob
+1  A: 

Jash, if you execute this script, does it give you the results you'd expect?

CREATE TABLE #T_Cardevent (CARDNO VARCHAR(3), CARDEVENTDATE VARCHAR(8), CARDEVENTTIME VARCHAR(8))

INSERT INTO #T_Cardevent VALUES ('121', '20090610', '025050')
INSERT INTO #T_Cardevent VALUES ('121', '20090611', '040000')
INSERT INTO #T_Cardevent VALUES ('121', '20090611', '050000')
INSERT INTO #T_Cardevent VALUES ('121', '20090611', '020000')
INSERT INTO #T_Cardevent VALUES ('122', '20090611', '030001')
INSERT INTO #T_Cardevent VALUES ('122', '20090611', '030000')
INSERT INTO #T_Cardevent VALUES ('123', '20090611', '080000')
INSERT INTO #T_Cardevent VALUES ('123', '20090611', '100000')
INSERT INTO #T_Cardevent VALUES ('123', '20090611', '132449')
INSERT INTO #T_Cardevent VALUES ('123', '20090611', '025959')
INSERT INTO #T_Cardevent VALUES ('124', '20090610', '030000')
INSERT INTO #T_Cardevent VALUES ('124', '20090612', '030001')
INSERT INTO #T_Cardevent VALUES ('125', '20090611', '030002')
INSERT INTO #T_Cardevent VALUES ('125', '20090612', '040000')

SELECT     
  RowNumber = IDENTITY (int, 1, 1)
  , CARDNO
  , CARDEVENTDATE
  , CARDEVENTTIME 
INTO #Table
FROM #T_CARDEVENT 

SELECT t1.CARDNO, t1.CARDEVENTDATE, t1.CARDEVENTTIME  
FROM #Table t1 
     INNER JOIN (
        SELECT RowNumber = MIN(RowNumber), CARDEVENTDATE, CARDNO 
        FROM #Table t  
        GROUP BY cardno, cardeventdate  
        UNION ALL SELECT MAX(RowNumber), CARDEVENTDATE, CARDNO 
        FROM #Table t 
        GROUP BY cardno, cardeventdate) t2 ON t2.rownumber = t1.rownumber
ORDER BY 1, 2, 3

DROP TABLE #Table
DROP TABLE #T_Cardevent
Lieven
good one. need to add join on ID column as well though
van
also not sure if it works when the clustered index is not corresponding to the order the rows were inserted there.
van
@van: nice catch. I've updated the query. As for the clustered index, you are right and I've warned the OP about the non-deterministic execution of the query.
Lieven
am using sub query's - id from one table and date and value from another table, from that how can i create a temp table?
INSERT INTO #TableSELECT t1.ID, t2.Date, t2.ValueFROM (Table1Query) t1 JOIN (Table2Query) t2 ON t1.Whatever=t2.Whatever.
Lieven
Lieven, I understood, but am not using 7 column, am using n number of column, how can i insert all the n number of data's
@Jash. You do NOT need to create a temp table: Lieven just used it as a test for his query. You should only adapt his query to match your table and column names.
van
Am using sql server 2000 is not supporting the row number(), any function instead of row number()?
I would suggest you'd create a temporary table with an Identity column being the rownumber. You can then replace every ROW_NUMBER with this identity column.
Lieven
@Jash, the response is adjusted to include a SQLServer 2000 example
Lieven
Lieven not clear? what response is adjusted
@Lieven: I Go throgh the query, but i have to create a temp table for the row_number's. Suppose am using n number of column like day by day column is adding. so how i can create a temp table?
@Jash, I've separated the test data from the actual query doing the work. All you need to do is change the @Table reference in the SQL2000 example to your real tablename (or select)
Lieven
@Lieven: while executing the query - 389902 row affected, so no error in the query, thank you, but nothing display in the outputHow can i get a affected row data's?
@Jash: Add a SELECT * FROM #Table (before the DROP TABLE #Table )
Lieven
@Lieven: GO Drop TABLE #Table is not executing showing error, without this query is executing successfully, how i have to delete a temp table
@Lieven, Row Number is Created for all column in the temp table, From that how can i select a id, date, top value and Bottom value from the temp table
@Jash, perhaps if you post your entire script you have up until now, we will be better equiped to help you. As it stands, the script I provided works as expected. I have no idea why it doesn't give any results at your end.
Lieven
@Lieven, Don't me a mistake, am new to sql, your query is executing correctly. while executing this query, select * from temp table nothing output is displayed. That's y again i asked you? I don't know y nothing display in the output
@Jash, I'm sorry, without looking at your actual query, I have no clue as where to look for an error. Like I said, please post your query.
Lieven
@Lieven: SELECT RowNumber = IDENTITY (int, 1, 1), Cardno, cardeventdate, Cardeventtime INTO #Table FROM T_Cardevent SELECT t1.CARDNO, t1.CARDEVENTDATE, t1.CARDEVENTIME FROM #Table t1 INNER JOIN (SELECT RowNumber = MIN(RowNumber), CARDEVENTDate, CARDNO FROM #Table t GROUP BY t .CARDEVENTDate, t .CARDNO UNION ALL SELECT MAX(RowNumber), CARDEVENTDate, CARDNO FROM #Table t GROUP BY t .CARDEVENTDate, t .CARDNO) t2 ON t2.CARDNO = t1.CARDNO AND t2.CARDEVENTDate = t1.CARDEVENTDate AND t2.RowNumber = t1.RowNumberThis is My original Query – Here am getting cardno, cardeventdate, cardeventtime
@Jash: I assume it should be CARDEVENTTIME. You missed one T.
Lieven
@Lieven: cardno, cardeventdate, cardeventtime -> From this Query am selecting cardno, Cardeventdate, min time, max time. So Min Time and Max Time should take top column and botton column value for the particular date
@Lieven: Am not getting the First Time and Last time for the particular date, It's displaying all.
@Jash: I can only assure you that the testexamples you presented work with the queries presented here. If these queries don't allow you to get to the results you need, you'r better off launching a new, different formulated question instead of us trying to resolve this through comments. If you formulate a new question, make "sure" you give an accurate representation of data you are working with and what output you expect. The data you presented with this question obviously does not leed to the expected result.
Lieven
@Lieven: I edited my question, Exactly what i need. Please go though and help me.
A: 

Here's the solution using inline views:

with 
tempFirst as (
    select id, date, value, 
     row_number() over (partition by id, date order by date asc) as rownum1
    from table1
),
tempLast as ( 
    select *, 
     row_number() over (partition by id, date order by rownum1 desc) as rownum2 
    from tempFirst
)
select id, date, value from tempFirst where rownum1 = 1
union
select id, date, value from tempLast where rownum2 = 1

I have tested the output, which is:

ID  DATE       VALUE
001 2009-04-23 APPLE
001 2009-04-23 ROSE
001 2009-04-24 BERRY
001 2009-04-24 SILVER
Rashmi Pandit
While Executing the above query, it's showing error, Here i have start "with table" or select? Am using sub queries id from first table and date and value from second table. So I will work in sub queries?
You have to start from 'with tempFirst as .... rownum2 =1' ... I created a sample table with your values and tested on sqlserver. It gave me the desired result. What is the error that you are getting?
Rashmi Pandit
Incorrect syntax near "as" - showing error am using sql server 2000
WITH tempFirst AS (SELECT cardno, cardeventdate, cardeventtime, row_number() OVER (partition BY cardno, cardeventdate ORDER BY cardeventdate ASC) AS rownum1 FROM t_cardevent), tempLast AS(SELECT *, row_number() OVER (partition BY cardno, cardeventdateORDER BY rownum1 DESC) AS rownum2 FROM tempFirst) SELECT cardno, cardeventdate, cardeventtime FROM tempFirst WHERE rownum1 = 1UNION SELECT cardno, cardeventdate, cardeventtime FROM tempLast WHERE rownum2 = 1 From the above query, it showing error in incorrect syntax nearn "as".
SQL 2000 doesnt support row_number(). I am using SQL 2005. I'll check if there is any work around for this.
Rashmi Pandit
@Rashmi: SQL 2000, How can i write a query for this condition
Doesn't Lieven's approach work for you? He has specifically mentioned SQL2000
Rashmi Pandit
Am Using Sub Queries, Identity is not accepting in sub query, See My QuerySELECT T_PERSON.CARDNO, T_CARDEVENT.CARDEVENTDATE AS CardEvenDateAdjusted, T_CARDEVENT.CARDEVENTTIME FROM (SELECT RowNumber = IDENTITY (int, 1, 1), T_Person.CARDNO, .....) "While Executing this query it showing identity error".
@Rashmi: I edited my question, Exactly what i need. Please go through and help me