Sql Question

  • I am getting the below result set from a query.

    ItemidRegionIdQuantity

    4003510

    4134520

    40035570

    41345540

    41745590

    417555100

    41345650

    41745660

    41755615

    RegionId 55 has total 4 items among all the RegionIds in the result set.

    RegionId 5 has 2 and RegionId 56 has 3.

    I want the final result set in such a way that ItemIds 4134 and 4137 are available for RegionId 55,but are not available for RegionId 5

    so I want to add these 2 Items for Regiond 5 with Quantity=0 and like wise ItemId 4003 for Regionid 56.

    I need to modify the result set with a query and not the query that bring the result set.

    so the final result set would look like:

    ItemidRegionIdQuantity

    4003510

    4134520

    417450

    417550

    40035570

    41345540

    41745590

    417555100

    4003560

    41345650

    41745660

    41755615

    Can I do it with a Query or use Cursors or Loops?

    Thanks.

  • How about this?

    ; WITH CTE (ItemID, RegionID, Quantity) AS

    (

    SELECT 4003, 5 ,10

    UNION ALL SELECT 4134, 5 ,20

    UNION ALL SELECT 4003, 55, 70

    UNION ALL SELECT 4134, 55 ,40

    UNION ALL SELECT 4174, 55 ,90

    UNION ALL SELECT 4175, 55 ,100

    UNION ALL SELECT 4134, 56 ,50

    UNION ALL SELECT 4174, 56 ,60

    UNION ALL SELECT 4175, 56 ,15

    )

    , DistinctItemID AS

    (

    SELECT DISTINCT T1.ItemID

    FROM CTE T1

    )

    , DistinctRegionID AS

    (

    SELECT DISTINCT T1.RegionID

    FROM CTE T1

    )

    , FullList AS

    (

    SELECT It.ItemID , Rg.RegionID

    FROM DistinctItemID It

    CROSS JOIN DistinctRegionID Rg

    )

    SELECT Base.ItemID , Base.RegionID

    , Quantity = ISNULL ( CTE.Quantity , 0)

    FROM FullList Base

    LEFT JOIN CTE

    ON Base.ItemID = CTE.ItemID

    AND Base.RegionID = CTE.RegionID ;

    If my guess is right, this wont be scaling so well as we are touching the base table thrice to arrive at the results. There may be better options, but this all i can think of right now.. Let me think through and get back to u or let us wait for other good folks to jump on this!

    And please look at how i set up the sample data for other to work on; in future follow the same method so that your queries are answered fast!

    For the benefit of others who are try to give this a shot:

    IF OBJECT_ID('TempDB..#Temp') IS NOT NULL

    DROP TABLE #Temp;

    CREATE TABLE #Temp

    (

    ItemID INT

    , RegionID INT

    , Quantity INT

    )

    INSERT INTO #Temp (ItemID, RegionID, Quantity)

    SELECT 4003, 5 ,10

    UNION ALL SELECT 4134, 5 ,20

    UNION ALL SELECT 4003, 55, 70

    UNION ALL SELECT 4134, 55 ,40

    UNION ALL SELECT 4174, 55 ,90

    UNION ALL SELECT 4175, 55 ,100

    UNION ALL SELECT 4134, 56 ,50

    UNION ALL SELECT 4174, 56 ,60

    UNION ALL SELECT 4175, 56 ,15

    IF OBJECT_ID('TempDB..#Temp') IS NOT NULL

    DROP TABLE #Temp;

  • Normally I'm a big fan of using CTEs to improve readability but in this case, I think I'd just write it like this:

    DECLARE @Temp TABLE

    (

    ItemID INT

    , RegionID INT

    , Quantity INT

    )

    INSERT INTO @Temp (ItemID, RegionID, Quantity)

    SELECT 4003, 5 ,10

    UNION ALL SELECT 4134, 5 ,20

    UNION ALL SELECT 4003, 55, 70

    UNION ALL SELECT 4134, 55 ,40

    UNION ALL SELECT 4174, 55 ,90

    UNION ALL SELECT 4175, 55 ,100

    UNION ALL SELECT 4134, 56 ,50

    UNION ALL SELECT 4174, 56 ,60

    UNION ALL SELECT 4175, 56 ,15

    SELECT x.ItemID, y.RegionID, ISNULL(t.Quantity,0) As Quantity

    FROM(SELECT ItemID FROM @Temp GROUP BY ItemID) x

    CROSS JOIN (SELECT RegionID FROM @Temp GROUP BY RegionID) y

    LEFT OUTER JOIN @Temp t ON t.ItemID = x.ItemID and t.RegionID = y.RegionID

    I think the idea to create a Cartesian product of unique ItemID and RegionID is the right approach, I just did it a little different.

    Note that this solution is no more scalable than the first (execution plans looked identical on first glance).


    My mantra: No loops! No CURSORs! No RBAR! Hoo-uh![/I]

    My thought question: Have you ever been told that your query runs too fast?

    My advice:
    INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?
    The path of least resistance can be a slippery slope. Take care that fixing your fixes of fixes doesn't snowball and end up costing you more than fixing the root cause would have in the first place.

    Need to UNPIVOT? Why not CROSS APPLY VALUES instead?[/url]
    Since random numbers are too important to be left to chance, let's generate some![/url]
    Learn to understand recursive CTEs by example.[/url]
    [url url=http://www.sqlservercentral.com/articles/St

  • There is a way to get a better query plan:

    INSERT INTO @Temp (ItemID, RegionID, Quantity)

    SELECT 4003, 5 ,10

    UNION ALL SELECT 4134, 5 ,20

    UNION ALL SELECT 4003, 55, 70

    UNION ALL SELECT 4134, 55 ,40

    UNION ALL SELECT 4174, 55 ,90

    UNION ALL SELECT 4175, 55 ,100

    UNION ALL SELECT 4134, 56 ,50

    UNION ALL SELECT 4174, 56 ,60

    UNION ALL SELECT 4175, 56 ,15

    SELECT x.ItemID, y.RegionID, MAX(ISNULL(t.Quantity,0)) As Quantity

    FROM(SELECT ItemID FROM @Temp) x

    CROSS APPLY (SELECT RegionID FROM @Temp) y

    LEFT OUTER JOIN @Temp t ON t.ItemID = x.ItemID and t.RegionID = y.RegionID

    GROUP BY x.ItemID, y.RegionID

    Still no guarantees that it will perform better in practice. Best to run both with STATISTICS TIME and IO ON for a larger record set to be sure.


    My mantra: No loops! No CURSORs! No RBAR! Hoo-uh![/I]

    My thought question: Have you ever been told that your query runs too fast?

    My advice:
    INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?
    The path of least resistance can be a slippery slope. Take care that fixing your fixes of fixes doesn't snowball and end up costing you more than fixing the root cause would have in the first place.

    Need to UNPIVOT? Why not CROSS APPLY VALUES instead?[/url]
    Since random numbers are too important to be left to chance, let's generate some![/url]
    Learn to understand recursive CTEs by example.[/url]
    [url url=http://www.sqlservercentral.com/articles/St

  • dwain.c

    Thanks for all the help!!!

Viewing 5 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic. Login to reply