Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Anyway to do this in TSQL (2005) without a cursor?

Posted on 2008-10-07
9
Medium Priority
?
222 Views
Last Modified: 2010-03-19
using SQL Server 2005;

I have two tables: Demand and Supply.  I need to determine for each record in the demand table which record in supply table it can consume.

These are the demand and supply table and sample data.

CREATE TABLE Demand
( Priority INT,
Food VARCHAR(10),
      Qty INT)
      
INSERT INTO Demand
      Select 1, 'Apples', 2
      UNION ALL
      Select 2, 'Apples', 5
      UNION ALL
      Select 3, 'Apples', 4
      UNION ALL
      Select 4, 'Apples', 10
      UNION ALL
      Select 5, 'Apples', 15


CREATE TABLE Supply
( SourceID INT,
Food VARCHAR(10),
      Qty INT)
      
INSERT INTO Supply
      Select 1, 'Apples', 10
      UNION ALL
      Select 2, 'Apples', 20
      UNION ALL
      Select 3, 'Apples', 5


----------------------------------
The end result I'm trying to obtain is like so:
Priority      Food      Qty            SupplyID
1      Apples      2            1
2      Apples      5            1
3      Apples      4            2
4      Apples      10            2
5      Apples      15            NULL

Thanks,
sopheak
0
Comment
Question by:sopheak
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
9 Comments
 

Author Comment

by:sopheak
ID: 22664759
I guess it would be okay to use a cursor in answer too, it may be faster depending on the amount of data.
0
 
LVL 60

Expert Comment

by:Kevin Cross
ID: 22664865
I don't have my SQL Management Studio, but this should parse out fine.
-- create a view for demand
CREATE VIEW dbo.vw_DemandTotalsByFoodAndPriority AS
;WITH demandCTE AS (
    SELECT *, row_number() OVER (PARTITION BY Food ORDER BY Priority) As dRow
    FROM Demand
)
SELECT d1.Food, d1.Priority, d1.Qty, d1.Qty + IsNull(d2.Qty, 0) AS TotalDemand
FROM demandCTE d1 LEFT JOIN demandCTE d2
ON d1.Food = d2.Food AND d1.dRow - 1 = d2.dRow;
GO
 
-- create a view for supply
CREATE VIEW vw_SupplyTotalsByFoodAndSourceID AS
;WITH supplyCTE AS (
    SELECT *, row_number() OVER (PARTITION BY Food ORDER BY SourceID) As sRow
    FROM Supply
)
SELECT s1.Food, s1.SourceID, s1.Qty, s1.Qty + IsNull(s2.Qty, 0) AS TotalSupply
FROM supplyCTE s1 LEFT JOIN supplyCTE s2
ON s1.Food = s2.Food AND s1.sRow - 1 = s2.sRow;
GO
 
SELECT d.Priority, d.Food, d1.Qty, s.SourceID
FROM vw_DemandTotalsByFoodAndPriority d LEFT JOIN vw_SupplyTotalsByFoodAndSourceID s
ON d.Food = s.Food AND d.TotalDemand <= s.TotalSupply
ORDER BY 2, 1

Open in new window

0
 
LVL 60

Expert Comment

by:Kevin Cross
ID: 22664883
Sorry,filled with type-o's -- use THIS:
-- create a view for demand
CREATE VIEW dbo.vw_DemandTotalsByFoodAndPriority AS
WITH demandCTE AS (
    SELECT *, row_number() OVER (PARTITION BY Food ORDER BY Priority) As dRow
    FROM Demand
)
SELECT d1.Food, d1.Priority, d1.Qty, d1.Qty + IsNull(d2.Qty, 0) AS TotalDemand
FROM demandCTE d1 LEFT JOIN demandCTE d2
ON d1.Food = d2.Food AND d1.dRow - 1 = d2.dRow;
 
-- create a view for supply
CREATE VIEW vw_SupplyTotalsByFoodAndSourceID AS
WITH supplyCTE AS (
    SELECT *, row_number() OVER (PARTITION BY Food ORDER BY SourceID) As sRow
    FROM Supply
)
SELECT s1.Food, s1.SourceID, s1.Qty, s1.Qty + IsNull(s2.Qty, 0) AS TotalSupply
FROM supplyCTE s1 LEFT JOIN supplyCTE s2
ON s1.Food = s2.Food AND s1.sRow - 1 = s2.sRow;
 
SELECT        Priority, Food, Qty,
                             (SELECT        MIN(SourceID) AS Expr1
                               FROM            vw_SupplyTotalsByFoodAndSourceID AS s
                               WHERE        (d.Food = Food) AND (d.TotalDemand <= TotalSupply)) AS SupplyID
FROM            vw_DemandTotalsByFoodAndPriority AS d
ORDER BY Food, Priority

Open in new window

0
Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

 

Author Comment

by:sopheak
ID: 22669786
unfortunately the results don't come out correct;  this is the result from your solution.  For Example, record 3 cannot pull from supplyID 1 because record 1 and 2 already consumed a total of 9 ,so only one is left.  Record 3 should pull the remainder from supplyid 2.

I guess I need to clarify that I want the last supply line a record would pull from to satify the demand.

tahnks

Priority      Food      Qty      SupplyID
1      Apples      2      1
2      Apples      5      1
3      Apples      4      1
4      Apples      10      2
5      Apples      15      2

0
 
LVL 60

Accepted Solution

by:
Kevin Cross earned 1000 total points
ID: 22670038
Check the views independently and make sure the total demands look correct.  Should go 2, 7, 11, and so on.  I will check when I get home as I have this data loaded there and I got results you requested when I tested last night.
0
 
LVL 60

Expert Comment

by:Kevin Cross
ID: 22670107
Sorry I posted the wrong code version... I will post in a few minutes.
0
 

Author Comment

by:sopheak
ID: 22670674
I modified your Demand view and it works now:

CREATE VIEW dbo.vw_DemandTotalsByFoodAndPriority AS
WITH demandCTE AS (
    SELECT *, row_number() OVER (PARTITION BY Food ORDER BY Priority) As dRow
    FROM Demand
)
SELECT  d1.Food,
        d1.Priority,
        d1.Qty,
        (SELECT SUM(Qty)
            FROM demandCTE
            WHERE d1.Food = Food AND d1.dRow >= dRow) AS 'TotalDemand'
FROM    demandCTE d1
0
 
LVL 60

Expert Comment

by:Kevin Cross
ID: 22670717
This is what I meant to post, sorry!
DROP VIEW vw_SupplyTotalsByFoodAndSourceID
GO
DROP VIEW vw_DemandTotalsByFoodAndPriority
GO
 
-- create a view for demand
CREATE VIEW dbo.vw_DemandTotalsByFoodAndPriority AS
SELECT d1.Food, d1.Priority, d1.Qty
, d1.Qty + IsNull((SELECT SUM(QTY) FROM demand d2 WHERE d2.Food = d1.Food AND d2.Priority < d1.Priority ), 0) AS TotalDemand
FROM demand d1;
 GO
-- create a view for supply
CREATE VIEW vw_SupplyTotalsByFoodAndSourceID AS
SELECT s1.Food, s1.SourceID, s1.Qty
, s1.Qty + IsNull((SELECT SUM(QTY) FROM supply s2 WHERE s1.Food = s2.Food AND s2.SourceID < s1.SourceID ), 0) AS TotalSupply
FROM supply s1
 GO
 
SELECT        Priority, Food, Qty,
                             (SELECT        MIN(SourceID) AS Expr1
                               FROM            vw_SupplyTotalsByFoodAndSourceID AS s
                               WHERE        (d.Food = Food) AND (d.TotalDemand <= TotalSupply)) AS SupplyID
FROM            vw_DemandTotalsByFoodAndPriority AS d
ORDER BY Food, Priority

Open in new window

0
 
LVL 60

Expert Comment

by:Kevin Cross
ID: 22670743
Glad you figured it out as well.  I apologize as I saw that needed to include all the rows previous to current one instead of the last one.  
0

Featured Post

Enroll in October's Free Course of the Month

Do you work with and analyze data? Enroll in October's Course of the Month for 7+ hours of SQL training, allowing you to quickly and efficiently store or retrieve data. It's free for Premium Members, Team Accounts, and Qualified Experts!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: When running hybrid database environments, you often need to query some data from a remote db of any type, while being connected to your MS SQL Server database. Problems start when you try to combine that with some "user input" pass…
This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question