0

This is the opposite of reducing repeating records. SQL query to create physical inventory checklists If widget-xyz has a qty of 1 item return 1 row, but if it has 5, return 5 rows etc. For all widgets in a particular warehouse.

Previously this was handled with a macro working through a range in excel, checking the qty column. Is there a way to make a single query instead?

The tables are FoxPro dbf files generated by an application and I am outputting this into html

1
  • The answer to this question is highly dependent on the datbase platform that you're using. SQL Server? Oracle? Access? Commented Nov 7, 2009 at 21:46

4 Answers 4

3

Instead of generating an xml string and using xml parsing functions to generate a counter as Nestor has suggested, you might consider joining on a recursive CTE as a counter, as LukLed has hinted to:

WITH Counter AS
(
    SELECT 0 i

    UNION ALL

    SELECT i + 1
    FROM Counter
    WHERE i < 100
),
Data AS
(
    SELECT 'A' sku, 1 qty
    UNION
    SELECT 'B', 2
    UNION
    SELECT 'C', 3
)
SELECT * 
FROM Data
    INNER JOIN Counter ON i < qty

According to query analyzer, this query is much faster than the xml pseudo-table. This approach also gives you a recordset with a natural key (sku, i).

There is a default recursion limit of 100 in MSSQL that will restrict your counter. If you have quantities > 100, you can either increase this limit, use nested counters, or create a physical table for counting.

Sign up to request clarification or add additional context in comments.

Comments

1

For SQL 2005/2008, take a look at

CROSS APPLY

What I would do is CROSS APPLY each row with a sub table with as many rows as qty has. A secondary question is how to create that sub table (I'd suggest to create an xml string and then parse it with the xml operators) I hope this gives you a starting pointer....

Starting with

declare @table table (sku int, qty int);
insert into @table values (1, 5), (2,4), (3,2);
select * from @table;

sku         qty
----------- -----------
1           5
2           4
3           2

You can generate:

with MainT as (
    select *, convert(xml,'<table>'+REPLICATE('<r></r>',qty)+'</table>') as pseudo_table
    from @table 
)
select p.sku, p.qty
from MainT p 
CROSS APPLY 
(
    select p.sku from p.pseudo_table.nodes('/table/r') T(row)
) crossT


sku         qty
----------- -----------
1           5
1           5
1           5
1           5
1           5
2           4
2           4
2           4
2           4
3           2
3           2

Is that what you want? Seriously dude... next time put more effort writing your question. It's impossible to know exactly what you are looking for.

1 Comment

Using the idea to create a table with as many rows as qty, I tried something like this, and then do a query similar to this: SELECT widgets.SKU FROM widgets INNER JOIN RowAmts ON widgets.QTY=RowAmts.qty; However the prospect of creating a giant table with 100 rows of 100 or 99 rows of 99 of rows just seems wrong. Or is it?
1

You can use table with number from 1 to max(quantity) and join your table by quantity <= number. You can do it in many ways, but it depends on sql engine.

2 Comments

is there a simple example of a join like this I could refer to?
FoxPro tables and usually constructing stuff in mssql or access first, then I reproduce what works in a webpage
-1

You can do this using dynamic sql.

2 Comments

access and mssql, but the tables are vfp
That will just add a new level of complexity to the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.