| Author |
Topic |
|
zeeshan13
Constraint Violating Yak Guru
347 Posts |
Posted - 2008-02-12 : 12:49:57
|
| Hi All,I have a table called saleshistory with the following fields and types.Date (datetime)StoreID (varchar)ProductID (varchar)Cost(decimal)Price(Decimal)Units (BigInt)The above saleshistory table has numerous distinct products, numerous distinct Outlets and numerous dictinct dates.The saleshistory table holds the saleshistory information in a real retail world enviornment. So each record represents the units sold by each product per store per date with a particular price and cost.The total number of records that this table holds is 5513828. Please note that the saleshistory table always has one record per store per date per product.The Saleshistory records look like as follows (This is just an example. Each field is seperated by coma)(Its sorted by date Desc order)Date, StoreID, ProductID, Cost, Price,Units2008-01-21 00:00:00 041FCS 134009 0.00 13.20 1.002008-01-14 00:00:00 041FCS 134009 0.00 13.20 4.002007-12-24 00:00:00 041FCS 134009 0.00 12.00 3.002007-12-17 00:00:00 041FCS 134009 0.00 12.00 2.002007-12-10 00:00:00 041FCS 134009 6.47 12.00 2.002007-12-03 00:00:00 041FCS 134009 0.00 12.00 2.002007-11-26 00:00:00 041FCS 134009 5.00 12.00 3.002007-11-19 00:00:00 041FCS 134009 0.00 12.00 2.00Now in this table there are numerous instances where the cost is 0. I want to get the non zero cost (where cost>0) on a latest date (if exsist) for each product per date per outlet and then apply this cost for the remaining dates available.Look at the above example (Please note that its for same product & same outlet).The non zero cost available on the latest date is $6.47 on '2007-12-10'. Now only from '2007-12-10' to ownwards I want to apply this cost in my SELECT statement, the price and units will always remain unchanged. So my SELECT should return the following:Date, StoreID, ProductID, Cost, Price,Units2008-01-21 00:00:00 041FCS 134009 6.47 13.20 1.002008-01-14 00:00:00 041FCS 134009 6.47 13.20 4.002007-12-24 00:00:00 041FCS 134009 6.47 12.00 3.002007-12-17 00:00:00 041FCS 134009 6.47 12.00 2.002007-12-10 00:00:00 041FCS 134009 6.47 12.00 2.002007-12-03 00:00:00 041FCS 134009 0.00 12.00 2.002007-11-26 00:00:00 041FCS 134009 5.00 12.00 3.002007-11-19 00:00:00 041FCS 134009 0.00 12.00 2.00I want to do the same for each set of product per date per outlet. Look at some another examplesExample 2; (make sure its same product & outlet)Date, StoreID, ProductID, Cost, Price,Units2007-01-21 00:00:00 041TCS 234008 0.0 13.20 1.002007-01-14 00:00:00 041TCS 234008 4.0 13.20 4.002006-12-24 00:00:00 041TCS 234008 5.0 12.00 3.00Example 2 Should return:Date, StoreID, ProductID, Cost, Price,Units2007-01-21 00:00:00 041TCS 234008 4.0 13.20 1.002007-01-14 00:00:00 041TCS 234008 4.0 13.20 4.002006-12-24 00:00:00 041TCS 234008 5.0 12.00 3.00In example 2 the non zero cost (4.0) on the latest date (2007-01-14) has been applied to the only other available date (2007-01-21).Example3(make sure its same product & outlet):Date, StoreID, ProductID, Cost, Price,Units2007-02-21 00:00:00 041TCS 134555 2.0 13.20 1.002007-01-14 00:00:00 041TCS 134555 0.0 13.20 4.002006-12-24 00:00:00 041TCS 134555 0.0 12.00 3.00Example 3 Should return:Date, StoreID, ProductID, Cost, Price,Units2007-02-21 00:00:00 041TCS 134555 2.0 13.20 1.002007-01-14 00:00:00 041TCS 134555 0.0 13.20 4.002006-12-24 00:00:00 041TCS 134555 0.0 12.00 3.00Note in example 3 that the SELECT return everything same, because there is no zero cost for this product in this outlet.In the end my SELECT should return all 5513828 records including cost applied (where applicable). The price and units always remin same.How can I write a SELECT query for that.Can someone please help me as soon as possible. Thanks a million for all your help.Zee |
|
|
zeeshan13
Constraint Violating Yak Guru
347 Posts |
Posted - 2008-02-12 : 13:50:52
|
| Can ayone help please????Thanks a million....Zee |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-02-12 : 14:40:49
|
This is untested and I have no idea how the performance will be but...who know, maybe it'll work :)declare @saleshistory table (Date datetime,StoreID varchar(10),ProductID varchar(10),Cost money,Price money,Units BigInt);insert @salesHistoryselect '2008-01-21 00:00:00', '041FCS', '134009', 0.00, 13.20, 1.00 union allselect '2008-01-14 00:00:00', '041FCS', '134009', 0.00, 13.20, 4.00 union allselect '2007-12-24 00:00:00', '041FCS', '134009', 0.00, 12.00, 3.00 union allselect '2007-12-17 00:00:00', '041FCS', '134009', 0.00, 12.00, 2.00 union allselect '2007-12-10 00:00:00', '041FCS', '134009', 6.47, 12.00, 2.00 union allselect '2007-12-03 00:00:00', '041FCS', '134009', 0.00, 12.00, 2.00 union allselect '2007-11-26 00:00:00', '041FCS', '134009', 5.00, 12.00, 3.00 union allselect '2007-11-19 00:00:00', '041FCS', '134009', 0.00, 12.00, 2.00 union allselect '2007-01-21 00:00:00', '041TCS', '234008', 0.0, 13.20, 1.00 union allselect '2007-01-14 00:00:00', '041TCS', '234008', 4.0, 13.20, 4.00 union allselect '2006-12-24 00:00:00', '041TCS', '234008', 5.0, 12.00, 3.00 union allselect '2007-02-21 00:00:00', '041TCS', '134555', 2.0, 13.20, 1.00 union allselect '2007-01-14 00:00:00', '041TCS', '134555', 0.0, 13.20, 4.00 union allselect '2006-12-24 00:00:00', '041TCS', '134555', 0.0, 12.00, 3.00;with cost (storeid, productid, date, cost)as( select StoreID ,ProductID ,max(Date) ,convert(money, substring(max( convert(char(23), date, 121) + convert(varchar(20), cost) ), 23+1, 20)) from @salesHistory where Cost > 0 group by StoreID ,ProductID)select sh.date ,sh.StoreID ,sh.ProductID ,Cost = case when isNull(sh.cost,0) = 0 and sh.date > c.date then c.cost else sh.cost end ,sh.Price ,sh.Unitsfrom @salesHistory shleft join cost c on c.storeid = sh.storeid and c.productid = sh.productidorder by sh.StoreID ,sh.ProductID ,sh.date descOUTPUT:date StoreID ProductID Cost Price Units----------------------- ---------- ---------- --------------------- --------------------- --------------------2008-01-21 00:00:00.000 041FCS 134009 6.47 13.20 12008-01-14 00:00:00.000 041FCS 134009 6.47 13.20 42007-12-24 00:00:00.000 041FCS 134009 6.47 12.00 32007-12-17 00:00:00.000 041FCS 134009 6.47 12.00 22007-12-10 00:00:00.000 041FCS 134009 6.47 12.00 22007-12-03 00:00:00.000 041FCS 134009 0.00 12.00 22007-11-26 00:00:00.000 041FCS 134009 5.00 12.00 32007-11-19 00:00:00.000 041FCS 134009 0.00 12.00 22007-02-21 00:00:00.000 041TCS 134555 2.00 13.20 12007-01-14 00:00:00.000 041TCS 134555 0.00 13.20 42006-12-24 00:00:00.000 041TCS 134555 0.00 12.00 32007-01-21 00:00:00.000 041TCS 234008 4.00 13.20 12007-01-14 00:00:00.000 041TCS 234008 4.00 13.20 42006-12-24 00:00:00.000 041TCS 234008 5.00 12.00 3 EDIT:I added your sample data just to make sure something worked.Does Units need to be BIGINT?Be One with the OptimizerTG |
 |
|
|
zeeshan13
Constraint Violating Yak Guru
347 Posts |
Posted - 2008-02-12 : 16:50:08
|
| TG,Thanks for your help.But how I can run the select part alone (without inserts) again the saleshistory table. I am struggling. Can you please help. |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-02-12 : 17:02:34
|
| Take just the SELECT part alone, change the table name from @salesHistory to SalesHistory (two places).I used a table variable (with inserted data) to test the query.Be One with the OptimizerTG |
 |
|
|
zeeshan13
Constraint Violating Yak Guru
347 Posts |
Posted - 2008-02-12 : 17:17:26
|
| TG,When I am running the following, it give me an erorr: Msg 208, Level 16, State 1, Line 11Invalid object name 'cost'.Any ide what is wrong here?( select StoreID ,ProductID ,max(Date) ,convert(money, substring(max( convert(char(23), date, 121) + convert(varchar(20), cost) ), 23+1, 20)) from salesHistory where Cost > 0 group by StoreID ,ProductID)select sh.date ,sh.StoreID ,sh.ProductID ,Cost = case when isNull(sh.cost,0) = 0 and sh.date > c.date then c.cost else sh.cost end ,sh.Price ,sh.Unitsfrom salesHistory shleft join cost c on c.storeid = sh.storeid and c.productid = sh.productidorder by sh.StoreID ,sh.ProductID ,sh.date desc |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2008-02-12 : 17:20:12
|
| you are missing this above your statement:;with cost (storeid, productid, date, cost)asEDIT:I highlighted the SELECT portion in my first post in blueBe One with the OptimizerTG |
 |
|
|
zeeshan13
Constraint Violating Yak Guru
347 Posts |
Posted - 2008-02-12 : 19:23:01
|
| Just need to ask one more thing. What if I want to insert the records of your select query in a temperoray table (for example; select * into #t from table) how can I do that in your query. The reason why I asked is that I have never work with a select query the way you are doing...so please let me know.Thank you so much for your help.Zee |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-02-12 : 19:46:01
|
[code]-- Prepare sample data to mimic your environmentDECLARE @Sample TABLE (Date DATETIME, StoreID CHAR(6), ProductID INT, Cost SMALLMONEY, Price SMALLMONEY, Units SMALLMONEY)INSERT @SampleSELECT '2008-01-21 00:00:00', '041FCS', '134009', 0.00, 13.20, 1.00 UNION ALLSELECT '2008-01-14 00:00:00', '041FCS', '134009', 0.00, 13.20, 4.00 UNION ALLSELECT '2007-12-24 00:00:00', '041FCS', '134009', 0.00, 12.00, 3.00 UNION ALLSELECT '2007-12-17 00:00:00', '041FCS', '134009', 0.00, 12.00, 2.00 UNION ALLSELECT '2007-12-10 00:00:00', '041FCS', '134009', 6.47, 12.00, 2.00 UNION ALLSELECT '2007-12-03 00:00:00', '041FCS', '134009', 0.00, 12.00, 2.00 UNION ALLSELECT '2007-11-26 00:00:00', '041FCS', '134009', 5.00, 12.00, 3.00 UNION ALLSELECT '2007-11-19 00:00:00', '041FCS', '134009', 0.00, 12.00, 2.00 UNION ALLSELECT '2007-01-21 00:00:00', '041TCS', '234008', 0.0, 13.20, 1.00 UNION ALLSELECT '2007-01-14 00:00:00', '041TCS', '234008', 4.0, 13.20, 4.00 UNION ALLSELECT '2006-12-24 00:00:00', '041TCS', '234008', 5.0, 12.00, 3.00 UNION ALLSELECT '2007-02-21 00:00:00', '041TCS', '134555', 2.0, 13.20, 1.00 UNION ALLSELECT '2007-01-14 00:00:00', '041TCS', '134555', 0.0, 13.20, 4.00 UNION ALLSELECT '2006-12-24 00:00:00', '041TCS', '134555', 0.0, 12.00, 3.00-- Show the expected outputSELECT s.Date, s.StoreID, s.ProductID, CASE WHEN s.Date >= d.Date AND s.Cost = 0.0 THEN d.Cost ELSE s.Cost END AS Cost, s.Price, s.UnitsFROM @Sample AS sINNER JOIN ( SELECT StoreID, ProductID, Cost, Date, ROW_NUMBER() OVER (PARTITION BY StoreID, ProductID ORDER BY Date DESC) AS RecID FROM @Sample WHERE Cost > 0.0 ) AS d ON d.StoreID = s.StoreID AND s.ProductID = d.ProductIDWHERE d.RecID = 1ORDER BY s.StoreID, s.ProductID, s.Date DESC[/code] E 12°55'05.25"N 56°04'39.16" |
 |
|
|
zeeshan13
Constraint Violating Yak Guru
347 Posts |
Posted - 2008-02-12 : 21:46:59
|
| Peso,I run your SELECT against the saleshistory table. This time I am getting 3570472 rows only, it should be 5513828 rows which is what TG's method was returning.Peso / TG can you please help?Thank u so much for the help.Zee |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-02-13 : 01:35:05
|
You have a working query from TG? Stick with that.I doubt they differ in speed or performance.SELECT s.Date, s.StoreID, s.ProductID, CASE WHEN s.Date >= d.Date AND s.Cost = 0.0 THEN d.Cost ELSE s.Cost END AS Cost, s.Price, s.UnitsFROM @Sample AS sLEFT JOIN ( SELECT StoreID, ProductID, Cost, Date, ROW_NUMBER() OVER (PARTITION BY StoreID, ProductID ORDER BY Date DESC) AS RecID FROM @Sample WHERE Cost > 0.0 ) AS d ON d.StoreID = s.StoreID AND s.ProductID = d.ProductID AND d.RecID = 1ORDER BY s.StoreID, s.ProductID, s.Date DESC E 12°55'05.25"N 56°04'39.16" |
 |
|
|
|
|
|