Note that there are some explanatory texts on larger screens.

plurals
  1. POTSQL equally divide resultset to groups and update them
    primarykey
    data
    text
    <p>I have my database with 3 tables like so:</p> <p><img src="https://i.stack.imgur.com/uPj06.jpg" alt="enter image description here"></p> <p>Orders table has data like below:</p> <pre><code>OrderID OperatorID GroupID OrderDesc Status Cash ... -------------------------------------------------------------------------- 1 1 1 small order 1 100 2 1 1 another order 2 0 3 1 2 xxxxxxxxxxx 2 1000 5 2 2 yyyyyyyyyyy 2 150 9 5 1 xxxxxxxxxxx 1 0 10 NULL 2 xxxxxxxxxxx 1 10 11 NULL 3 xxxxxxxxxxx 1 120 </code></pre> <p>Operators table:</p> <pre><code>OperatorID Name GroupID Active --------------------------------------- 1 John 1 1 2 Kate 1 1 4 Jack 2 1 5 Will 1 0 6 Sam 3 1 </code></pre> <p>Group table:</p> <pre><code>GroupID Name --------------- 1 G1 2 G2 3 X1 </code></pre> <p>As You can see John has 3 orders, Kate 1, Will 1, Jack and Sam none.<br /></p> <p>Now I would like to assign operators to orders base on some conditions:</p> <ul> <li>order must have cash>0</li> <li>order must have status=1</li> <li>order must be in group 1 or 2</li> <li>operator must be active (active=1)</li> <li>operator must be in group 1 or 2</li> </ul> <p>This is the result that I would like to get:</p> <pre><code>OrderID OperatorID GroupID OrderDesc Status Cash ... -------------------------------------------------------------------------- 1 1 1 small order 1 100 &lt; change 2 1 1 another order 2 0 3 2 2 xxxxxxxxxxx 2 1000 &lt; change 5 4 2 yyyyyyyyyyy 2 150 &lt; change 9 5 1 xxxxxxxxxxx 1 0 10 4 2 xxxxxxxxxxx 1 10 &lt; change 11 NULL 3 xxxxxxxxxxx 1 120 </code></pre> <p>I would like to shuffle orders and update operatorID so that every time I call this script I get randomly assigner operatorID, but every operator will have equal number or orders (close to equal, because if I have 7 orders one person will have 3 and rest 2).</p> <p>I can use <code>NTILE</code> to distribute orders into groups, but I need to assign operatorID to that group.</p> <p>I think that I need to do something like this:</p> <pre><code>SELECT NTILE(2) OVER( order by orderID desc) as newID,* FROM orders(NOLOCK) </code></pre> <p>This will give me my orders table grouped into equal parts. What I need to know is length of operators table (to add it as parameter to NTILE), after that I could join my results with operators (using <code>row_number()</code>)</p> <p>Is there a better solution?</p> <p>My question again: <strong>How to equally divide result set into groups and update that record set using another table data?</strong></p> <p><strong>EDIT:</strong> This is my code so far: <a href="http://sqlfiddle.com/#!3/39849/25" rel="nofollow noreferrer">http://sqlfiddle.com/#!3/39849/25</a></p> <p><strong>EDIT 2</strong> I've updated my question and added more conditions.</p> <p>I would like to assign operators to orders based on some conditions:</p> <ul> <li>order must have cash>0</li> <li>order must have status=1</li> <li>order must be in group 1 or 2</li> <li>operator must be active (active=1)</li> <li>operator must be in group 1 or 2</li> </ul> <p>I'm building this query as stored procedure.<br /> So the first step will be to generate data with new assignments into temporary table and after final approval in second step to update main table based on that temp table.</p> <p>I have 2 more questions:</p> <ol> <li><p>Will it be better to first select all all orders and all operators that meets the conditions to temporary table and then do the shuffling or to do it all in one big query?</p></li> <li><p>I would like to pass array or groups as a parameter to my procedure. Which option would be the best to pass array to stored procedure (SQL Server 2005).<br /><br /> I know this was asked many times but I would like to know if it is better to create a separate function that will cut comma separated string into table (<a href="http://www.sommarskog.se/arrays-in-sql-2005.html" rel="nofollow noreferrer">http://www.sommarskog.se/arrays-in-sql-2005.html</a>) or to put everything inside one big fat procedure? :)</p></li> </ol> <hr> <p><strong>FINAL ANSWER:</strong> avilable at <a href="http://sqlfiddle.com/#!3/afb48/2" rel="nofollow noreferrer">http://sqlfiddle.com/#!3/afb48/2</a></p> <pre><code>SELECT o.*, op.operatorName AS NewOperator, op.operatorID AS NewOperatorId FROM (SELECT o.*, (ROW_NUMBER() over (ORDER BY newid()) % numoperators) + 1 AS randseqnum FROM Orders o CROSS JOIN (SELECT COUNT(*) AS numoperators FROM operators WHERE operators.active=1) op WHERE o.cash&gt;0 and o.status in (1,3) ) o JOIN (SELECT op.*, ROW_NUMBER() over (ORDER BY newid()) AS seqnum FROM Operators op WHERE op.active=1 ) op ON o.randseqnum = op.seqnum ORDER BY o.orderID </code></pre> <p>Answer based on Gordon's Linoff answer. Thanks!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload