Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2005 Forums
 Transact-SQL (2005)
 query help

Author  Topic 

michaelb
Yak Posting Veteran

69 Posts

Posted - 2008-06-25 : 03:27:45
Hi,

I'm writing a query where I have a whole lot of transactions and each one has its own record. What I want to do is get a particular value from the last transaction in each month.

So I've got say 100 records with:
Transnum
Date
Calcprice
(there are other fields but irrelevant for this purpose I think)

I want to get the calcprice for the last record of each month. The date of the last record won't necessarily be the last day of the month. I have 6 months of data, so I need the calcprice from the last record dated in January, the last record dated in Feb and so on.

Not quite sure how to approach this one, any help would be much appreciated. Thanks!

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-25 : 03:33:03
[code]SELECT tmp.year,tmp.month,t.Calcprice FROM Table t
INNER JOIN (SELECT YEAR(Date) AS year,MONTH(Date) as month,Max(Date) as maxdate
FROM Table
GROUP BY YEAR(Date),MONTH(Date))tmp
ON tmp.maxdate=t.Date[/code]


Note that if you have multiple records on last date of any month then calaclprice from all of them will be retrieved seperately
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2008-06-25 : 03:34:04
[code]SELECT *
FROM (
SELECT Transnum, Date, Calcprice,
row_no = row_number() OVER (PARTITION BY DATEADD(MONTH, DATEDIFF(MONTH, 0, [Date]), 0)
ORDER BY [Date] DESC)
FROM TABLE
) t
WHERE row_no = 1[/code]


KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

michaelb
Yak Posting Veteran

69 Posts

Posted - 2008-06-25 : 03:40:05
quote:
Originally posted by visakh16

SELECT tmp.year,tmp.month,t.Calcprice FROM Table t
INNER JOIN (SELECT YEAR(Date) AS year,MONTH(Date) as month,Max(Date) as maxdate
FROM Table
GROUP BY YEAR(Date),MONTH(Date))tmp
ON tmp.maxdate=t.Date



Note that if you have multiple records on last date of any month then calaclprice from all of them will be retrieved seperately




Thanks. But how do I only retrieve a single result where there are multiples on the last date?
Go to Top of Page

michaelb
Yak Posting Veteran

69 Posts

Posted - 2008-06-25 : 03:41:51
quote:
Originally posted by khtan

SELECT *
FROM (
SELECT Transnum, Date, Calcprice,
row_no = row_number() OVER (PARTITION BY DATEADD(MONTH, DATEDIFF(MONTH, 0, [Date]), 0)
ORDER BY [Date] DESC)
FROM TABLE
) t
WHERE row_no = 1



KH
[spoiler]Time is always against us[/spoiler]





Thanks, but this is returning very limited data. I probably should have included that I also have an itemcode field. I will have a calcprice from the last date in the month for each itemcode.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-25 : 03:42:18
quote:
Originally posted by michaelb

quote:
Originally posted by visakh16

SELECT tmp.year,tmp.month,t.Calcprice FROM Table t
INNER JOIN (SELECT YEAR(Date) AS year,MONTH(Date) as month,Max(Date) as maxdate
FROM Table
GROUP BY YEAR(Date),MONTH(Date))tmp
ON tmp.maxdate=t.Date



Note that if you have multiple records on last date of any month then calaclprice from all of them will be retrieved seperately




Thanks. But how do I only retrieve a single result where there are multiples on the last date?


In that case what should be your result? Should it be any value of calcprice (min,maxor random) or you want their sum?
Go to Top of Page

michaelb
Yak Posting Veteran

69 Posts

Posted - 2008-06-25 : 03:47:40
quote:
Originally posted by visakh16

quote:
Originally posted by michaelb

quote:
Originally posted by visakh16

SELECT tmp.year,tmp.month,t.Calcprice FROM Table t
INNER JOIN (SELECT YEAR(Date) AS year,MONTH(Date) as month,Max(Date) as maxdate
FROM Table
GROUP BY YEAR(Date),MONTH(Date))tmp
ON tmp.maxdate=t.Date



Note that if you have multiple records on last date of any month then calaclprice from all of them will be retrieved seperately




Thanks. But how do I only retrieve a single result where there are multiples on the last date?


In that case what should be your result? Should it be any value of calcprice (min,maxor random) or you want their sum?





I probably should have included that I also have an itemcode field. I will have a calcprice from the last date in the month for each itemcode.

Calcprice is the moving average cost of the item at the time of the transaction. What I'm trying to do is get the moving cost of each item at the last day of the month, so retrieving this from the last transaction of the month per item will give me this.

Hope I'm making sense.

There is also a doctime field which maybe will be useful, it is a 4 digit number like a 24hr clock... ie 1510 = 3:10pm... so if we got the last date and last time? Also the transnum field is a unique identifier, the higher the transnum the later the transaction occurred.
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2008-06-25 : 03:50:54
Please, don't make us guess any more. Relieve our pain by reading and following the instructions in this blog post
http://weblogs.sqlteam.com/jeffs/archive/2008/05/13/question-needed-not-answer.aspx


E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-25 : 03:55:35
quote:
Originally posted by michaelb

quote:
Originally posted by visakh16

quote:
Originally posted by michaelb

quote:
Originally posted by visakh16

SELECT tmp.year,tmp.month,t.Calcprice FROM Table t
INNER JOIN (SELECT YEAR(Date) AS year,MONTH(Date) as month,Max(Date) as maxdate
FROM Table
GROUP BY YEAR(Date),MONTH(Date))tmp
ON tmp.maxdate=t.Date



Note that if you have multiple records on last date of any month then calaclprice from all of them will be retrieved seperately




Thanks. But how do I only retrieve a single result where there are multiples on the last date?


In that case what should be your result? Should it be any value of calcprice (min,maxor random) or you want their sum?





I probably should have included that I also have an itemcode field. I will have a calcprice from the last date in the month for each itemcode.

Calcprice is the moving average cost of the item at the time of the transaction. What I'm trying to do is get the moving cost of each item at the last day of the month, so retrieving this from the last transaction of the month per item will give me this.

Hope I'm making sense.

There is also a doctime field which maybe will be useful, it is a 4 digit number like a 24hr clock... ie 1510 = 3:10pm... so if we got the last date and last time? Also the transnum field is a unique identifier, the higher the transnum the later the transaction occurred.




SELECT tmp.year,tmp.month,t.Itemcode,t.Calcprice 
FROM Table t
INNER JOIN (SELECT YEAR(Date) AS year,MONTH(Date) as month,Itemcode,Max(Date) as maxdate
FROM Table
GROUP BY YEAR(Date),MONTH(Date),Itemcode)tmp
ON tmp.maxdate=t.Date
AND tmp.Itemcode=t.Itemcode



or use modified form of Khtans soln


SELECT Itemcode, Date, Calcprice
FROM (
SELECT Transnum,Itemcode, Date, Calcprice,
row_no = row_number() OVER (PARTITION BY YEAR(Date) AS year,MONTH(Date),Itemcode ORDER BY [Date] DESC)
FROM TABLE
) t
WHERE row_no = 1
Go to Top of Page

michaelb
Yak Posting Veteran

69 Posts

Posted - 2008-06-25 : 04:02:20
Thanks!
Go to Top of Page

khtan
In (Som, Ni, Yak)

17689 Posts

Posted - 2008-06-25 : 05:55:21
If you do try to understand what this code is doing, you will be able to modify it easily to suites your requirement.

SELECT *
FROM (
SELECT Transnum, Itemcode, Date, Calcprice,
row_no = row_number() OVER (PARTITION BY Itemcode, DATEADD(MONTH, DATEDIFF(MONTH, 0, [Date]), 0)
ORDER BY [Date] DESC)
FROM TABLE
) t
WHERE row_no = 1



KH
[spoiler]Time is always against us[/spoiler]

Go to Top of Page

michaelb
Yak Posting Veteran

69 Posts

Posted - 2008-06-25 : 06:24:08
Is there any way of getting each month's price in a seperate column rather than a seperate row?

I have the qty of each item on hand at the end of the month in a seperate table which I need to multiply by the price relevant to that month.

Something like the following, although I don't think this will work:
q.Jan * t.calcprice where tmp.month = 1
q.Feb * t.calcprice where tmp.month = 2
and so on
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-25 : 06:36:35
quote:
Originally posted by michaelb

Is there any way of getting each month's price in a seperate column rather than a seperate row?

I have the qty of each item on hand at the end of the month in a seperate table which I need to multiply by the price relevant to that month.

Something like the following, although I don't think this will work:
q.Jan * t.calcprice where tmp.month = 1
q.Feb * t.calcprice where tmp.month = 2
and so on


please post some sample data of what you want.
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2008-06-25 : 06:49:20
This message didn't ring a bell?
quote:
Originally posted by Peso

Please, don't make us guess any more. Relieve our pain by reading and following the instructions in this blog post
http://weblogs.sqlteam.com/jeffs/archive/2008/05/13/question-needed-not-answer.aspx



E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

michaelb
Yak Posting Veteran

69 Posts

Posted - 2008-06-25 : 06:50:34
My Qty Table has this data:
Item Code Jan Feb Mar
100100 10 5 3

What I want to get to is:
Item Code Jan Value Feb Value etc
100100 10*(Last Calcprice) 5*(Last Calcprice)

So my query needs to multiply the qty for each month from the qty table by the last calcprice for the month.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-25 : 06:53:29
use UNPIVOT to get your month values in rows and then join with earleir query to do the update
Go to Top of Page

michaelb
Yak Posting Veteran

69 Posts

Posted - 2008-06-25 : 06:55:26
cheers I'll give it a go
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-25 : 07:15:10
something like this (untested):-

SELECT m.Itemcode,m.Months,m.Value * n.Calcprice
(SELECT *
FROM
(SELECT ItemCode, Jan, Feb, Mar FROM QtyTable)t
UNPIVOT (Value FOR Months IN ([Jan],[Feb],...,[Dec]))p
)m
INNER JOIN (SELECT Itemcode, Date, Calcprice
FROM (
SELECT Transnum,Itemcode, Date, LEFT(DATENAME(mm,Date),3) AS MonthValue,
Calcprice,
row_no = row_number() OVER (PARTITION BY YEAR(Date) AS year,MONTH(Date),Itemcode ORDER BY [Date] DESC)
FROM TABLE
) t
WHERE row_no = 1
)n
ON m.Itemcode=n.Itemcode
AND m.MonthValue=n.Months
Go to Top of Page

michaelb
Yak Posting Veteran

69 Posts

Posted - 2008-06-25 : 20:43:04
Hi...

I've realised a gap in my theory.

If I have an item with no transactions in a particular month, there won't be a calcprice for the query to get. So I'm thinking I need to do the following somehow:
January will be last calcprice for transaction with date less than 31/01/2008
February will be last calcprice for transaction with date less than 28/02/2008
and so on

Any idea?

Cheers.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-26 : 00:22:02
quote:
Originally posted by michaelb

Hi...

I've realised a gap in my theory.

If I have an item with no transactions in a particular month, there won't be a calcprice for the query to get. So I'm thinking I need to do the following somehow:
January will be last calcprice for transaction with date less than 31/01/2008
February will be last calcprice for transaction with date less than 28/02/2008
and so on

Any idea?

Cheers.


I didnt get you there. Can you elaborate please?
Go to Top of Page

michaelb
Yak Posting Veteran

69 Posts

Posted - 2008-06-26 : 00:32:00
This is what I've come up with but I need to consolidate it somehow as the SQL server can't handle it. It was fine with 3 subqueries, but then I added 3 more and I get:
Could not allocate space for object '<temporary system object: 441772935675904>' in database 'tempdb' because the 'PRIMARY' filegroup is full. Create disk space by deleting unneeded files, dropping objects in the filegroup, adding additional files to the filegroup, or setting autogrowth on for existing files in the filegroup.

select t0.itemcode,
t0.jan,
s1.calcprice,
t0.jan * s1.calcprice,
t0.feb,
s2.calcprice,
t0.feb * s2.calcprice,
t0.mar,
s3.calcprice,
t0.mar * s3.calcprice,
t0.apr,
s4.calcprice,
t0.apr * s4.calcprice,
t0.may,
s5.calcprice,
t0.may * s5.calcprice,
t0.jun,
s6.calcprice,
t0.jun * s6.calcprice


from datamart.dbo.actualstock t0
left join
(Select t0.* FROM datamart.dbo.eomcosts t0
JOIN
(select itemcode,
MAX(docdate) docdate
from datamart.dbo.eomcosts
Where docdate < '2008/01/31'
Group By itemcode) t1
ON t0.docdate = t1.docdate AND
t0.itemcode = t1.itemcode) s1
on s1.itemcode = t0.itemcode

left join
(Select t0.* FROM datamart.dbo.eomcosts t0
JOIN
(select itemcode,
MAX(docdate) docdate
from datamart.dbo.eomcosts
Where docdate < '2008/02/28'
Group By itemcode) t1
ON t0.docdate = t1.docdate AND
t0.itemcode = t1.itemcode) s2
on s2.itemcode = t0.itemcode

left join
(Select t0.* FROM datamart.dbo.eomcosts t0
JOIN
(select itemcode,
MAX(docdate) docdate
from datamart.dbo.eomcosts
Where docdate < '2008/03/31'
Group By itemcode) t1
ON t0.docdate = t1.docdate AND
t0.itemcode = t1.itemcode) s3
on s3.itemcode = t0.itemcode

left join
(Select t0.* FROM datamart.dbo.eomcosts t0
JOIN
(select itemcode,
MAX(docdate) docdate
from datamart.dbo.eomcosts
Where docdate < '2008/04/30'
Group By itemcode) t1
ON t0.docdate = t1.docdate AND
t0.itemcode = t1.itemcode) s4
on s3.itemcode = t0.itemcode

left join
(Select t0.* FROM datamart.dbo.eomcosts t0
JOIN
(select itemcode,
MAX(docdate) docdate
from datamart.dbo.eomcosts
Where docdate < '2008/05/31'
Group By itemcode) t1
ON t0.docdate = t1.docdate AND
t0.itemcode = t1.itemcode) s5
on s3.itemcode = t0.itemcode

left join
(Select t0.* FROM datamart.dbo.eomcosts t0
JOIN
(select itemcode,
MAX(docdate) docdate
from datamart.dbo.eomcosts
Where docdate < '2008/06/30'
Group By itemcode) t1
ON t0.docdate = t1.docdate AND
t0.itemcode = t1.itemcode) s6
on s3.itemcode = t0.itemcode
Go to Top of Page
    Next Page

- Advertisement -