Author |
Topic |
maya_zakry
Constraint Violating Yak Guru
379 Posts |
Posted - 2007-02-21 : 22:22:12
|
hi all,anyone has any idea in what i want to accomplish here :-how can we sort the select statement, say, we want to compare integer inputqty=60.. how can we match the suitable sum of column qty to reach the 60 figure...EG -> qty column : 50, 25, 15, 10i)how can we prompt the select statemnet to choose 50 and 10 to make it 60... ii)for another eg, say inputqty=90, then how can we prompt it to select 50 + 25 + 15 = 90iii)and for some cases, if no round qty, the sum could be more, but the least from the qty list... eg : inputqty=80, how to automate the select statement to choose the closest figure, 50 + 25 + 10 = 85i dunno if this is possible for any select or function or sp...thankss....~~~Focus on problem, not solution~~~ |
|
khtan
In (Som, Ni, Yak)
17689 Posts |
Posted - 2007-02-21 : 22:34:14
|
I remember just sometime back, there is a similar question and Peter provided the solution. Can't seems to find it now. Don't worry, The Saint will comes to the rescue soon. KH |
 |
|
khtan
In (Som, Ni, Yak)
17689 Posts |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-02-22 : 00:44:49
|
You spent 1 hour, 13 minutes and 33 seconds to find it?Impressive!Peter LarssonHelsingborg, Sweden |
 |
|
khtan
In (Som, Ni, Yak)
17689 Posts |
Posted - 2007-02-22 : 01:31:01
|
quote: Originally posted by Peso You spent 1 hour, 13 minutes and 33 seconds to find it?Impressive!Peter LarssonHelsingborg, Sweden
No really. Just suddenly recall the keyword 'algorithm' but have to search by 'algo' due to poster misspelled it. KH |
 |
|
maya_zakry
Constraint Violating Yak Guru
379 Posts |
Posted - 2007-02-22 : 01:32:55
|
ohh KHTAN...before i start reading the post.. would like to thank u first..peso! and u spent sometime to count on the time! :P~~~Focus on problem, not solution~~~ |
 |
|
maya_zakry
Constraint Violating Yak Guru
379 Posts |
Posted - 2007-02-22 : 01:39:12
|
oh mann.. this will take sometime to study .. dont even know where to start!! ~~~Focus on problem, not solution~~~ |
 |
|
khtan
In (Som, Ni, Yak)
17689 Posts |
Posted - 2007-02-22 : 01:41:07
|
quote: Originally posted by maya_zakry ohh KHTAN...before i start reading the post.. would like to thank u first..peso! and u spent sometime to count on the time! :P~~~Focus on problem, not solution~~~
Don't forget to thank Peter for the algorithm  KH |
 |
|
maya_zakry
Constraint Violating Yak Guru
379 Posts |
Posted - 2007-02-22 : 02:16:20
|
yup.. ive run the thing.. wow.. unbelieveable... i could just call it in my Sp.. tq.. really good thing peter!~~~Focus on problem, not solution~~~ |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-02-22 : 02:19:32
|
You're welcome!Peter LarssonHelsingborg, Sweden |
 |
|
maya_zakry
Constraint Violating Yak Guru
379 Posts |
Posted - 2007-02-22 : 02:23:11
|
wait,(maybe this quite silly Q :( ! ) how to customade the table we use.. in my case, i want to use tblitemdetail and compare the originqty column.. doo i have to change something in the function or what> pliz help.. thanks a lot~~~Focus on problem, not solution~~~ |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-02-22 : 02:30:31
|
Yes, you have to change the INSERT statement to the @Stage table variable, ie change the source of the insert, and the column names fro the INSERT for the source columns.Peter LarssonHelsingborg, Sweden |
 |
|
maya_zakry
Constraint Violating Yak Guru
379 Posts |
Posted - 2007-02-22 : 02:59:10
|
peter,ive try to customade the insert variables :--- Stage the dataDECLARE @Stage TABLE (RowID INT IDENTITY(0, 1), Number MONEY, UniqueID VARCHAR(12)) INSERT @Stage ( Number, UniqueID ) SELECT OriginQty AS Number, ItemStorageID AS UniqueID FROM [tblItemDetail] where itemid='Flower'i)in my tblitemdetail, my originqty is in float type, is that ok?ii) this table also have many records to filter around 30k and above, until now, it is still processing my request(>5 mins) :-select * FROm fnGetAnyCombination(30) is this normal? or maybe i misunderstanding anything.. thanks~~~Focus on problem, not solution~~~ |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-02-22 : 03:12:48
|
You have 30k records to insert into the @stage table?That is ok, but remember that the number of permutations are 2^30 to check later.That is somewhat equal to 1 000 000 000 combinations to check. That could take a while... How many unique combinations for OriginQty and ItemStorageID do you have? If there are a lot of duplicates, only insert distinct values.Also, you could try the improved version posted later in the topic linked above!If all OriginQty are positive, there is an speed improvement for the function.How many uniqu values forPeter LarssonHelsingborg, Sweden |
 |
|
maya_zakry
Constraint Violating Yak Guru
379 Posts |
Posted - 2007-02-22 : 03:24:21
|
yup, my itemstorageid is unique, exists only once in a tbl..umm... is it correct if i add restiction in the function insert statement, in my tblitemdetail likeSELECT OriginQty ,ItemStorageID FROM [tblItemDetail] where itemid='Flower'okay, suppose this normal statement will produce only 40 rows.. but when applying to the function until now it still processing the function.. that is too slow.. something i did wrong or what?~~~Focus on problem, not solution~~~ |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-02-22 : 03:36:26
|
Do you really need all the combinations possible? or is the first combination enough?Use the last version of the function in the link above.SELECT * FROM dbo.fnGetAnyCombination(30, 1, 0) Peter LarssonHelsingborg, Sweden |
 |
|
maya_zakry
Constraint Violating Yak Guru
379 Posts |
Posted - 2007-02-22 : 03:43:14
|
the first and closest combination is enuff.. okay ill try that new version first.. and also, i try on the smaller table size.. around 30-40 records... and still it's too slow.. am i on track .. uwwawawawwawawaaaaaaaaaaaaand unfortunately, my originqty is not uniueq, only itemstorageid, itemstorageid : A1,A2,A3 could have same originqty ~~~Focus on problem, not solution~~~ |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-02-22 : 03:49:39
|
The drawback feature with the function is that it brute-force tests all combinations!There are other ways to go, if you only want the closest sum, or the first sum found...Peter LarssonHelsingborg, Sweden |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-02-22 : 03:51:56
|
Post the 30-40 records you have, and your expected output of them, and I will try to write some new algorithm to fetch them.Peter LarssonHelsingborg, Sweden |
 |
|
maya_zakry
Constraint Violating Yak Guru
379 Posts |
Posted - 2007-02-22 : 04:08:58
|
ItemStorageID OriginQtyIS0607523 899IS0607526 100IS0607725 95IS0607730 50IS0607731 55IS0607732 40IS0607733 5IS0607981 100IS0607982 100IS0607983 100IS0607984 100IS0607985 100IS0607986 50IS0607990 250IS0607991 100IS0608003 100IS0608004 100IS0608005 100IS0608006 100IS0608007 100IS0608008 100IS0608010 100IS0608011 100IS0608014 90IS0608034 100IS0608035 100IS0608036 100IS0608037 100IS0608038 100IS0608039 100IS0608046 50IS0608047 350IS0608833 450IS0608834 450IS0608835 100IS0608840 100IS0608842 50IS0608843 50IS0608f011 50IS0609117 1IS0609770 10IS0609846 1-first i dun know how ppl post records and output here in the forum.. for me, i paste in execl and repaste here...-from the records,just wanna find the closest combination base on some restriction in my where statement(to consider many things lik,e expirydate, location) but for now, need to make this originqty combination up first..~~~Focus on problem, not solution~~~ |
 |
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-02-22 : 06:05:22
|
With the test data above, try this! It takes me only 2 seconds the get the nearest match for the wanted sum 349!-- Initialize the search parameterDECLARE @WantedValue INTSELECT @WantedValue = 349-- Stage the source dataDECLARE @Data TABLE ( RecID INT IDENTITY(1, 1) PRIMARY KEY CLUSTERED, MaxItems INT, CurrentItems INT DEFAULT 0, FaceValue INT, BestUnder INT DEFAULT 0, BestOver INT DEFAULT 1 )-- Aggregate the source dataINSERT @Data ( MaxItems, FaceValue )SELECT COUNT(*), QtyFROM ( SELECT 899 AS Qty UNION ALL SELECT 100 UNION ALL SELECT 95 UNION ALL SELECT 50 UNION ALL SELECT 55 UNION ALL SELECT 40 UNION ALL SELECT 5 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 50 UNION ALL SELECT 250 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 90 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 50 UNION ALL SELECT 350 UNION ALL SELECT 450 UNION ALL SELECT 450 UNION ALL SELECT 100 UNION ALL SELECT 100 UNION ALL SELECT 50 UNION ALL SELECT 50 UNION ALL SELECT 50 UNION ALL SELECT 1 UNION ALL SELECT 10 UNION ALL SELECT 1 ) AS dGROUP BY QtyORDER BY Qty DESC-- Declare some control variablesDECLARE @CurrentSum INT, @BestUnder INT, @BestOver INT, @RecID INT-- If productsum is less than or equal to the wanted sum, select all items!IF (SELECT SUM(MaxItems * FaceValue) FROM @Data) <= @WantedValue BEGIN SELECT MaxItems AS Items, FaceValue FROM @Data RETURN END-- Delete all unworkable FaceValues DELETEFROM @DataWHERE FaceValue > (SELECT MIN(FaceValue) FROM @Data WHERE FaceValue >= @WantedValue)-- Update MaxItems to a proper valueUPDATE @DataSET MaxItems = CASE WHEN 1 + (@WantedValue - 1) / FaceValue < MaxItems THEN 1 + (@WantedValue - 1) / FaceValue ELSE MaxItems END-- Update BestOver to a proper valueUPDATE @DataSET BestOver = MaxItems-- Initialize the control mechanismSELECT @RecID = MIN(RecID), @BestUnder = 0, @BestOver = SUM(BestOver * FaceValue)FROM @Data-- Do the loop!WHILE @RecID IS NOT NULL BEGIN -- Reset all "bits" not incremented UPDATE @Data SET CurrentItems = 0 WHERE RecID < @RecID -- Increment the current "bit" UPDATE @Data SET CurrentItems = CurrentItems + 1 WHERE RecID = @RecID -- Get the current sum SELECT @CurrentSum = SUM(CurrentItems * FaceValue) FROM @Data WHERE CurrentItems > 0 -- Stop here if the current sum is equal to the sum we want IF @CurrentSum = @WantedValue BREAK ELSE -- Update the current BestUnder if previous BestUnder is less IF @CurrentSum > @BestUnder AND @CurrentSum < @WantedValue BEGIN UPDATE @Data SET BestUnder = CurrentItems SET @BestUnder = @CurrentSum END ELSE -- Update the current BestOver if previous BestOver is more IF @CurrentSum > @WantedValue AND @CurrentSum < @BestOver BEGIN UPDATE @Data SET BestOver = CurrentItems SET @BestOver = @CurrentSum END -- Find the next proper "bit" to increment SELECT @RecID = MIN(RecID) FROM @Data WHERE CurrentItems < MaxItems ENDIF @RecID IS NULL IF @WantedValue - @BestUnder < @BestOver - @WantedValue -- If BestUnder is closer to the sum we want, choose that SELECT BestUnder AS Items, FaceValue FROM @Data WHERE BestUnder > 0 ELSE -- If BestOver is closer to the sum we want, choose that SELECT BestOver AS Items, FaceValue FROM @Data WHERE BestOver > 0ELSE -- We have an exact match SELECT CurrentItems AS Items, FaceValue FROM @Data WHERE CurrentItems > 0 Peter LarssonHelsingborg, Sweden |
 |
|
Next Page
|