| Author |
Topic |
|
stickmus
Starting Member
3 Posts |
Posted - 2009-03-24 : 06:10:08
|
Hi allFirst post, have been lurking for a while though. Great forum, helped me loadsI've got a cursor situation that I'm hoping you guys can help with.I'm importing data from an excel spreadsheet with carrier pricing information in the formatband_start|band_end|zone1_charge|zone2_charge|...0|0.5|0.51|1.23|...0.5|1|0.58|1.30|... What I need to do is get this into a table egzoneref|bandref|charge1|1|0.511|2|0.582|1|1.232|2|1.30 The issue is that there are 20 zones and 1000 bandsI was using a nested cursor to process the information, which was taking over an hour. I've re-factored to a single cursor which gets me down to about 7 minutes, but I'm hoping there's a better way.FORSELECT [min], [max], eu1, eu2, eu3, eu4, eu5, eu6, eu7, eu8, eu9, eu10, eu11, eu12, eu13, eu14, eu15, eu16, eu17, eu18, eu19, air3, air4, air5, air6, air7, air8, air9, code, zonerefFROM #imp_carrierpricing, zonematchingOPEN bandFETCH NEXT FROM band INTO @min, @max, @eu1, @eu2, @eu3, @eu4, @eu5, @eu6, @eu7, @eu8, @eu9, @eu10, @eu11, @eu12, @eu13, @eu14, @eu15, @eu16, @eu17, @eu18, @eu19, @air3, @air4, @air5, @air6, @air7, @air8, @air9, @zonecode, @zonerefWHILE (@@FETCH_STATUS <> -1)BEGIN IF (@@FETCH_STATUS <> -2) BEGIN -- all the above stuff is just to get the values from each band into the cursor variables -- we need to check if this band already exists SELECT @bandref = ref from deliverymethodband WHERE low = @min AND high = @max IF @bandref IS NULL BEGIN -- if it doesn't lets create a band for it --PRINT 'null' INSERT INTO deliverymethodband (code, description, type, low, high) SELECT CAST(@max * 2 AS INT), CAST(@min AS VARCHAR(5)) + '-' + CAST(@max AS VARCHAR(5)), 'W', @min, @max END DECLARE @charge MONEY -- let's case the values, not very nice to look at, but it works SET @charge = CASE WHEN @zonecode = 'EU1' THEN @EU1 WHEN @zonecode = 'EU2' THEN @EU2 ... WHEN @zonecode = 'AIR8' THEN @AIR8 WHEN @zonecode = 'AIR9' THEN @AIR9 END -- lets just make sure we have a charge... IF @charge is not null BEGIN -- work out if we're updating/inserting IF ( EXISTS ( SELECT * FROM deliverymethodzonecharge WHERE deliveryref = @deliveryref AND zoneref= @zoneref AND bandref = @bandref ) ) -- update BEGIN UPDATE deliverymethodzonecharge SET charge = @charge WHERE deliveryref = @deliveryref AND zoneref= @zoneref AND bandref = @bandref END ELSE --insert BEGIN INSERT INTO deliverymethodzonecharge (deliveryref, zoneref, bandref, charge) VALUES(@deliveryref, @zoneref, @bandref, @charge) END END SET @bandref = NULL SET @charge = NULL FETCH NEXT FROM band INTO @min, @max, @eu1, @eu2, @eu3, @eu4, @eu5, @eu6, @eu7, @eu8, @eu9, @eu10, @eu11, @eu12, @eu13, @eu14, @eu15, @eu16, @eu17, @eu18, @eu19, @air3, @air4, @air5, @air6, @air7, @air8, @air9, @zonecode, @zoneref ENDENDCLOSE bandDEALLOCATE band I'm fairly new to sql (6 months now) so any hints on any other things I'm doing horribly wrong also gratefully received (I'm not proud)TIAGeorge. |
|
|
heavymind
Posting Yak Master
115 Posts |
Posted - 2009-03-24 : 07:02:43
|
| from first glance I think you need PIVOTThanks, VadymMCITP DBA 2005/2008Chief DBA at http://www.db-staff.com |
 |
|
|
stickmus
Starting Member
3 Posts |
Posted - 2009-03-24 : 07:25:33
|
Okay, so looks like I've gone down the wrong route (UNION)Is this wrong? It's much faster!Is there a way to update rather than delete and recreate? Do I need to worry about this? The data is correct and will work if deleted and recreated, but there's about 26000 rows every time, will this cause problems?Sorry for all the questions.DELETE from deliverymethodzonecharge where zoneref in (select ref from deliveryzone where code like 'EU%' or code like 'AIR%')INSERT INTO deliverymethodzonecharge (bandref, zoneref, charge, deliveryref)SELECT *FROM(SELECT d.ref as bandref, z.ref as zoneref, v.eu1 as charge, @deliveryref as deliveryrefFROM #vko_imp_carrierpricing v, deliverymethodband d, deliveryzone zWHERE d.low = v.min AND d.high = v.max AND z.code = 'EU1'unionSELECT d.ref as bandref, z.ref as zoneref, v.eu2 as charge, @deliveryref as deliveryrefFROM #vko_imp_carrierpricing v, deliverymethodband d, deliveryzone zWHERE d.low = v.min AND d.high = v.max AND z.code = 'EU2'union...SELECT d.ref as bandref, z.ref as zoneref, v.air8 as charge, @deliveryref as deliveryrefFROM #vko_imp_carrierpricing v, deliverymethodband d, deliveryzone zWHERE d.low = v.min AND d.high = v.max AND z.code = 'AIR8'unionSELECT d.ref as bandref, z.ref as zoneref, v.air9 as charge, @deliveryref as deliveryrefFROM #vko_imp_carrierpricing v, deliverymethodband d, deliveryzone zWHERE d.low = v.min AND d.high = v.max AND z.code = 'AIR9')a |
 |
|
|
stickmus
Starting Member
3 Posts |
Posted - 2009-03-24 : 08:25:01
|
| Actually I managed to modify the above to run as an update. I've learned something today.Next time I think I need to use a cursor, I will think again. And I will have a look at that pivot at some point too. |
 |
|
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2009-03-24 : 09:12:24
|
| Actually you'll probably want to use UNPIVOT. |
 |
|
|
|
|
|