SQL Beginner

  • I have a table in this format:

    Origin Destination Tonnage(Kton)

    AlabamaArizona 0.0012

    Alabama Idaho 1.2

    Idaho Alaska 644

    Arizona Alaska 665

    .........

    Consisting of all the 50 states of USA as origin and destination

    Is it possible that from this table i can get data like this:

    Origin Destination KTon

    Alabama Arizona 0.0012

    Arizona Alabama 788

    Alabama Idaho 1.2

    Idaho Alabama 666

    Idaho Alaska 644

    Alaska Idaho 456

    ....

    ie, Examples with destinations acting as an origin and origin acting as a destination

    One possibility that i thought was

    If in the original data i filter it with respect to each origin ie. a table for one origin and hence around 50 tables

    and then perform a sql query which related the origin of one to destination of other and gives tonnage values for every example but this will take me a lot of time as for every 2 tables i need to write an sql statement hence 50P2(Permutation) possibilities.

    If some one could help in this respect then i'll be obliged

  • Your desired output doesn’t match the test data. Should we assume that, for example, “Arizona Alabama 788” is also in the original table?

    I’m also not clear about 50 tables. Do you have 1 table or 50? Are you thinking about creating 50 tables and populating them with data from one original table?

    --Vadim R.

  • hey sorry forgot to mention this before

    arizona alabama 788 is also there in original data

    But lets say there is

    arizona alabama 0 i.e tonnage value=0

    data also there

    so what i want is not to show this data in the output

    ie. if there is no tonnage value in the return direction then output table should not have such values

    Also

    the original table is randomly arranged with the data

    what i want is the output to be only in this format

    Arizona Alabama 788

    Alabama Arizona 34

    ie. consecutively arranged in this way.

  • OK, I don't have time right now but here is the setup that you should have provided in your first post. Hopefully someone will help. If not, i'll take stab at it Monday.

    CREATE TABLE #Trips(

    Origin VARCHAR(50)

    ,Destination VARCHAR(50)

    ,Tonnage FLOAT

    );

    INSERT INTO #Trips(Origin, Destination, Tonnage)

    VALUES

    ('Alabama', 'Arizona', 0.0012),

    ('Alabama', 'Idaho', 1.2),

    ('Idaho', 'Alaska', 644),

    ('Arizona', 'Alaska', 665),

    ('Arizona', 'Alabama', 788),

    ('Alabama', 'Texas', 12),

    ('Idaho', 'Alabama', 666),

    ('Alaska', 'Idaho', 456),

    ('Alaska', 'Idaho', 0),

    ('Arizona', 'Michigan', 0)

    SELECT * FROM #Trips;

    DROP TABLE #Trips;

    BTW, what should happen with one way trips like the Texas above?

    --Vadim R.

  • Actually the data consist of tonnage from each and every origin to each and every destination .... For the return trip from Texas a tonnage value of 0 will be stored as actually there was no return trip ... In this kind of data I want output like the one I specified before ... Thnx for the help

  • to try and help out...I'll throw the following code into the conversation

    it may or may not be appropriate...but hopefully OP will reply with some code that helps us understand.

    USE [TEMPDB] -- safe place

    GO

    -- go and create some test data to play with

    IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Location]') AND type in (N'U'))

    DROP TABLE [dbo].[Location]

    GO

    CREATE TABLE [dbo].[Location](

    [LocationID] [varchar](1) NULL

    ) ON [PRIMARY]

    GO

    INSERT INTO [dbo].[Location]([LocationID])

    SELECT N'A' UNION ALL

    SELECT N'B' UNION ALL

    SELECT N'C' UNION ALL

    SELECT N'D' UNION ALL

    SELECT N'E'

    IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Trips]') AND type in (N'U'))

    DROP TABLE [dbo].[Trips]

    GO

    CREATE TABLE [dbo].[Trips](

    [Origin] [varchar](1) NULL,

    [Destnation] [varchar](1) NULL,

    [Tonnage] [int] NULL

    ) ON [PRIMARY]

    GO

    INSERT INTO [dbo].[Trips]([Origin], [Destnation], [Tonnage])

    SELECT N'A', N'B', 5 UNION ALL

    SELECT N'A', N'D', 2 UNION ALL

    SELECT N'B', N'A', 3 UNION ALL

    SELECT N'B', N'E', 7 UNION ALL

    SELECT N'B', N'A', 5 UNION ALL

    SELECT N'B', N'D', 2 UNION ALL

    SELECT N'C', N'A', 1 UNION ALL

    SELECT N'C', N'A', 18 UNION ALL

    SELECT N'D', N'C', 12 UNION ALL

    SELECT N'D', N'A', 5 UNION ALL

    SELECT N'D', N'E', 6 UNION ALL

    SELECT N'A', N'B', 12 UNION ALL

    SELECT N'D', N'C', 30 UNION ALL

    SELECT N'E', N'D', 100 UNION ALL

    SELECT N'D', N'E', 50 UNION ALL

    SELECT N'E', N'C', 12 UNION ALL

    SELECT N'E', N'A', 15

    --do some work to start playing with

    ;WITH cte AS

    (

    SELECT A.LocationID AS Origin ,

    B.LocationID AS Destination

    FROM

    Location A INNER JOIN Location B ON A.LocationID <> B.LocationID

    )

    SELECT CTE.Origin, CTE.Destination, SUM(COALESCE (Trips.Tonnage, 0)) AS TOTALS

    FROM CTE LEFT OUTER JOIN

    Trips ON CTE.Destination = Trips.Destnation AND CTE.Origin = Trips.Origin

    GROUP BY CTE.Origin, CTE.Destination

    HAVING (SUM(COALESCE (Trips.Tonnage, 0)) > 0)

    ORDER BY CTE.Origin, CTE.Destination

    edit to exclude zero tonnage trips

    ________________________________________________________________
    you can lead a user to data....but you cannot make them think
    and remember....every day is a school day

  • shikhar_0511 (8/25/2012)


    Actually the data consist of tonnage from each and every origin to each and every destination .... For the return trip from Texas a tonnage value of 0 will be stored as actually there was no return trip ... In this kind of data I want output like the one I specified before ... Thnx for the help

    Please write some insert statements that explain what the data looks like. Don't use real data, but mock up the real data types and structures.

    Also, once you have sample data, then explain what it means.

  • I am not sure but I think he is looking something like this ; and I am still scratching my head to do this in a proper way..

    CREATE TABLE #Trips(

    Origin VARCHAR(50)

    ,Destination VARCHAR(50)

    ,Tonnage FLOAT

    );

    INSERT INTO #Trips(Origin, Destination, Tonnage)

    VALUES

    ('Alabama', 'Arizona', 0.0012),

    ('Alabama', 'Idaho', 1.2),

    ('Idaho', 'Alaska', 644),

    ('Arizona', 'Alaska', 665),

    ('Arizona', 'Alabama', 788),

    ('Alabama', 'Texas', 12),

    ('Idaho', 'Alabama', 666),

    ('Alaska', 'Idaho', 456),

    ('Alaska', 'Idaho', 0),

    ('Arizona', 'Michigan', 0)

    CREATE TABLE #Trips1(

    Origin VARCHAR(50)

    ,Destination VARCHAR(50)

    ,Tonnage FLOAT

    );

    declare @originA varchar(50),@DestinationA varchar(50),@originB varchar(50),@destinationB varchar(50),

    @tonnageA float,@tonnageB float

    declare trip_cursor cursor for

    SELECT distinct a.origin as originA ,

    a.destination As destinationA,

    a.tonnage As tonnageA,

    b.origin as originB,

    b.destination as destinationB,

    b.tonnage as tonnageB FROM #Trips a

    outer apply #trips b

    where a.Origin=b.Destination

    and a.Destination=b.Origin

    and a.tonnage<>0

    and b.tonnage<>0

    open trip_cursor

    fetch next from trip_cursor into

    @originA ,@DestinationA ,@tonnageA,@originB ,@destinationB

    ,@tonnageB

    while @@FETCH_STATUS=0

    begin

    insert into #Trips1 values (@originA,@DestinationA,@tonnageA)

    insert into #Trips1 values (@originB,@DestinationB,@tonnageB)

    fetch next from trip_cursor into

    @originA ,@DestinationA ,@tonnageA,@originB ,@destinationB

    ,@tonnageB

    end

    close trip_cursor

    deallocate trip_cursor

    insert into #Trips1 (origin,destination,tonnage) select origin,destination,tonnage from #Trips where Tonnage<>0

    except select origin,destination,tonnage from #Trips1-- where tonnage <>0

    select * from #Trips1

    drop table #Trips1

    still looking for a good solution; it's weekend 😛

    ~ demonfox
    ___________________________________________________________________
    Wondering what I would do next , when I am done with this one :ermm:

  • shikhar_0511 (8/25/2012)


    hey sorry forgot to mention this before

    arizona alabama 788 is also there in original data

    But lets say there is

    arizona alabama 0 i.e tonnage value=0

    data also there

    so what i want is not to show this data in the output

    ie. if there is no tonnage value in the return direction then output table should not have such values

    Also

    the original table is randomly arranged with the data

    what i want is the output to be only in this format

    Arizona Alabama 788

    Alabama Arizona 34

    ie. consecutively arranged in this way.

    I've worked with truck shipments and other delivery logistics/tracking before. You really need a truck number and a delivery date in the data. Do you have those in the data? If not, this project is pretty much dead because you'll never be able to correlate and sort the data properly.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Jeff is probably right, of course.

    However I thought I'd try this using a quirk I've seen in CROSS APPLY VALUES with respect to the order of the results that it returns.

    So let's try this:

    CREATE TABLE #Trips

    (Origin VARCHAR(50), Destination VARCHAR(50), Tonnage FLOAT);

    INSERT INTO #Trips(Origin, Destination, Tonnage)

    VALUES

    ('Alabama', 'Arizona', 0.0012),

    ('Alabama', 'Idaho', 1.2),

    ('Alabama', 'Alaska', 12),

    ('Idaho', 'Alaska', 644),

    ('Idaho', 'Alabama', 666),

    ('Idaho', 'Arizona', 667),

    ('Arizona', 'Alaska', 665),

    ('Arizona', 'Alabama', 788),

    ('Arizona', 'Idaho', 588),

    ('Alaska', 'Idaho', 456),

    ('Alaska', 'Arizona', 0),

    ('Alaska', 'Alabama', 0)

    ;WITH CTE AS (

    SELECT c.Origin, c.Destination, c.Tonnage

    ,n=ROW_NUMBER() OVER (ORDER BY (SELECT NULL))

    FROM #Trips a

    CROSS APPLY #Trips b

    CROSS APPLY (

    VALUES (a.Origin, a.Destination, a.Tonnage)

    ,(b.Origin, b.Destination, b.Tonnage)) c(Origin, Destination, Tonnage)

    WHERE (a.Origin = b.Destination AND b.Origin = a.Destination))

    SELECT Origin, Destination, Tonnage

    FROM (

    SELECT Origin, Destination, Tonnage

    FROM CTE a

    WHERE EXISTS (

    SELECT 1

    FROM CTE b

    WHERE b.n < a.n AND b.Origin = a.Origin AND b.Destination = a.Destination)) b

    --WHERE Tonnage <> 0

    DROP TABLE #Trips

    This returns these results:

    OriginDestinationTonnage

    IdahoAlabama666

    AlabamaIdaho1.2

    ArizonaAlabama788

    AlabamaArizona0.0012

    ArizonaIdaho588

    IdahoArizona667

    AlaskaIdaho456

    IdahoAlaska644

    AlaskaArizona0

    ArizonaAlaska665

    AlaskaAlabama0

    AlabamaAlaska12

    Which aside from the 0 tonnage values appears to be the sort order you want (or at least pretty darn close). The truly odd thing is that when I uncomment the WHERE Tonnage not equal 0, the query returns more rows than the above.

    There may be some way to rearrange the WHERE so this doesn't happen and actually eliminates the rows you want to remove but I'm clueless as to why it would return more rows.

    Someone will come along no doubt and say "quirks in CROSS APPLY VALUES aside, row ordering is not guaranteed," and I'd probably agree. Just thought I'd throw this into the mix.

    Jeff: Excuse the hidden RBAR. Just having some fun.


    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

  • Interesting. I found a way to force it to work.

    ;WITH CTE AS (

    SELECT c.Origin, c.Destination, c.Tonnage

    ,n=ROW_NUMBER() OVER (ORDER BY (SELECT NULL))

    FROM #Trips a

    CROSS APPLY #Trips b

    CROSS APPLY (

    VALUES (a.Origin, a.Destination, a.Tonnage)

    ,(b.Origin, b.Destination, b.Tonnage)) c(Origin, Destination, Tonnage)

    WHERE (a.Origin = b.Destination AND b.Origin = a.Destination))

    SELECT Origin, Destination, Tonnage

    FROM (

    SELECT TOP 12 Origin, Destination, Tonnage

    FROM CTE a

    WHERE EXISTS (

    SELECT 1

    FROM CTE b

    WHERE b.n < a.n AND b.Origin = a.Origin AND b.Destination = a.Destination)) b

    WHERE Tonnage <> 0

    Beats the bejeebers outta me as to why though.

    TOP 12 would need to be substituted by the known number of rows you expect to return (like 50*49 for all states?).


    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

  • Sorry. Let's try that one more time.

    ;WITH CTE1 AS (

    SELECT TOP 100 PERCENT Origin, Destination, Tonnage

    FROM #Trips

    ORDER BY Origin, Destination

    ),

    CTE AS (

    SELECT c.Origin, c.Destination, c.Tonnage

    ,n=ROW_NUMBER() OVER (ORDER BY (SELECT NULL))

    FROM CTE1 a

    CROSS APPLY CTE1 b

    CROSS APPLY (

    VALUES (a.Origin, a.Destination, a.Tonnage)

    ,(b.Origin, b.Destination, b.Tonnage)) c(Origin, Destination, Tonnage)

    WHERE (a.Origin = b.Destination AND b.Origin = a.Destination))

    SELECT Origin, Destination, Tonnage

    FROM (

    SELECT TOP 12 Origin, Destination, Tonnage

    FROM CTE a

    WHERE EXISTS (

    SELECT 1

    FROM CTE b

    WHERE b.n < a.n AND b.Origin = a.Origin AND b.Destination = a.Destination)) b

    WHERE Tonnage <> 0

    My last solution appeared to be affected by the order of the INSERTed records.


    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

  • I am really sorry but this one is definitely the final problem

    here is the new defined problem(forget about the old one):

    I m working on something called the analysis of deadhead route

    Deadhead route:

    a train, railroad car, airplane, truck, or other commercial vehicle while operating empty, as when returning to a terminal.For this i need to sort the data from the original data.

    Here is the original data set:

    create table Deadhead

    (origin varchar(50),

    destination varchar(50),

    tonnage float);

    Insert into Deadhead values

    ('Alabama','Alaska',788.88),

    ('Alabama','Texas',5665.88),

    ('Alabama','Arizona',6645),

    /*more Alabama data*/

    ('Alaska','Alabama',5546),

    ('Alaska','Texas',4556),

    /*more Alaska data*/

    ('Arizona','Alabama',73246),

    ('Arizona','Texas',273627)

    /*more Arizona data*/

    /* in between other data */

    ('Texas','Alabama',32756),

    ('Texas','Alaska',37257),

    ('Texas','Arizona',764236),

    /*more Texas data*/

    i.e. the data consist of tonnage values of transportation from 50 origins to 50 destinations arranged

    in an alphabetical order with respect to origin i.e. all tonnage values from Alabama as origin and to 50 other destinations comes first then tonnage values from Alaska to 50 other destination comes fsecond

    now here is what the output should look like

    'Alabama' , 'Alaska' , 788.88

    'Alaska' , 'Alabama', 5546

    'Alabama' , Arizona' , 6645

    'Arizona' , 'Alabama' , 73246

    'Alabama' , 'Texas' , 5665.88

    'Texas' , 'Alabama' , 32765

    i.e the output should be sorted in this manner and then further simple mathematical operators

    will be utilized on the above sorted data to calculate imbalance(difference) between a pair of origin and a destination tonnage value and then see whether that is significant to be considered as a deadhead route.

    For now just need the data to be sorted in the manner specified.

  • shikhar_0511 (8/26/2012)


    I am really sorry but this one is definitely the final problem

    here is the new defined problem(forget about the old one):

    I m working on something called the analysis of deadhead route

    Deadhead route:

    a train, railroad car, airplane, truck, or other commercial vehicle while operating empty, as when returning to a terminal.For this i need to sort the data from the original data.

    Here is the original data set:

    create table Deadhead

    (origin varchar(50),

    destination varchar(50),

    tonnage float);

    Insert into Deadhead values

    ('Alabama','Alaska',788.88),

    ('Alabama','Texas',5665.88),

    ('Alabama','Arizona',6645),

    /*more Alabama data*/

    ('Alaska','Alabama',5546),

    ('Alaska','Texas',4556),

    /*more Alaska data*/

    ('Arizona','Alabama',73246),

    ('Arizona','Texas',273627)

    /*more Arizona data*/

    /* in between other data */

    ('Texas','Alabama',32756),

    ('Texas','Alaska',37257),

    ('Texas','Arizona',764236),

    /*more Texas data*/

    i.e. the data consist of tonnage values of transportation from 50 origins to 50 destinations arranged

    in an alphabetical order with respect to origin i.e. all tonnage values from Alabama as origin and to 50 other destinations comes first then tonnage values from Alaska to 50 other destination comes fsecond

    now here is what the output should look like

    'Alabama' , 'Alaska' , 788.88

    'Alaska' , 'Alabama', 5546

    'Alabama' , Arizona' , 6645

    'Arizona' , 'Alabama' , 73246

    'Alabama' , 'Texas' , 5665.88

    'Texas' , 'Alabama' , 32765

    i.e the output should be sorted in this manner and then further simple mathematical operators

    will be utilized on the above sorted data to calculate imbalance(difference) between a pair of origin and a destination tonnage value and then see whether that is significant to be considered as a deadhead route.

    For now just need the data to be sorted in the manner specified.

    As long as your data is complete, i.e., you have 12 records for this case listing all of the 4*3 records (I added a couple to your test data to account for this), the below query will work (same as my previous post):

    create table #Deadhead

    (origin varchar(50),

    destination varchar(50),

    tonnage float);

    Insert into #Deadhead

    values

    ('Alabama','Alaska',788.88),

    ('Alabama','Texas',5665.88),

    ('Alabama','Arizona',6645),

    ('Alaska','Alabama',5546),

    ('Alaska','Texas',4556),

    ('Alaska','Arizona',921),

    /*more Alaska data*/

    ('Arizona','Alabama',73246),

    ('Arizona','Texas',273627),

    ('Arizona','Alaska',273) ,

    /*more Arizona data*/

    /* in between other data */

    ('Texas','Alabama',32756),

    ('Texas','Alaska',37257),

    ('Texas','Arizona',764236)

    /*more Texas data*/

    ;WITH CTE1 AS (

    SELECT TOP 100 PERCENT Origin, Destination, Tonnage

    FROM #Deadhead

    ORDER BY Origin, Destination

    ),

    CTE AS (

    SELECT c.Origin, c.Destination, c.Tonnage

    ,n=ROW_NUMBER() OVER (ORDER BY (SELECT NULL))

    FROM CTE1 a

    CROSS APPLY CTE1 b

    CROSS APPLY (

    VALUES (a.Origin, a.Destination, a.Tonnage)

    ,(b.Origin, b.Destination, b.Tonnage)) c(Origin, Destination, Tonnage)

    WHERE (a.Origin = b.Destination AND b.Origin = a.Destination))

    SELECT Origin, Destination, Tonnage

    FROM (

    SELECT TOP 12 Origin, Destination, Tonnage

    FROM CTE a

    WHERE EXISTS (

    SELECT 1

    FROM CTE b

    WHERE b.n < a.n AND b.Origin = a.Origin AND b.Destination = a.Destination)) b

    WHERE Tonnage <> 0

    DROP TABLE #Deadhead

    Results are (lists data by round trips):

    OriginDestinationTonnage

    AlaskaAlabama5546

    AlabamaAlaska788.88

    ArizonaAlabama73246

    AlabamaArizona6645

    ArizonaAlaska273

    AlaskaArizona921

    TexasAlabama32756

    AlabamaTexas5665.88

    TexasAlaska37257

    AlaskaTexas4556

    TexasArizona764236

    ArizonaTexas273627


    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

  • Or if your data is incomplete, as I have demonstrated by commenting out one of the set up rows, you can explode the CTE1 with a FULL OUTER JOIN to make it complete.

    create table #Deadhead

    (origin varchar(50),

    destination varchar(50),

    tonnage float);

    Insert into #Deadhead

    values

    ('Alabama','Alaska',788.88),

    ('Alabama','Texas',5665.88),

    ('Alabama','Arizona',6645),

    ('Alaska','Alabama',5546),

    ('Alaska','Texas',4556),

    --('Alaska','Arizona',921),

    /*more Alaska data*/

    ('Arizona','Alabama',73246),

    ('Arizona','Texas',273627),

    ('Arizona','Alaska',273) ,

    /*more Arizona data*/

    /* in between other data */

    ('Texas','Alabama',32756),

    ('Texas','Alaska',37257),

    ('Texas','Arizona',764236)

    /*more Texas data*/

    ;WITH CTE1 AS (

    SELECT TOP 100 PERCENT Origin=ISNULL(a.Origin, b.Destination)

    ,Destination=ISNULL(a.Destination, b.Origin)

    ,Tonnage=ISNULL(a.Tonnage, 0)

    FROM #Deadhead a

    FULL OUTER JOIN #Deadhead b

    ON a.Origin = b.Destination AND b.Origin = a.Destination

    ORDER BY ISNULL(a.Origin, b.Destination), ISNULL(a.Destination, b.Origin)

    ),

    CTE AS (

    SELECT c.Origin, c.Destination, c.Tonnage

    ,n=ROW_NUMBER() OVER (ORDER BY (SELECT NULL))

    FROM CTE1 a

    CROSS APPLY CTE1 b

    CROSS APPLY (

    VALUES (a.Origin, a.Destination, a.Tonnage)

    ,(b.Origin, b.Destination, b.Tonnage)) c(Origin, Destination, Tonnage)

    WHERE (a.Origin = b.Destination AND b.Origin = a.Destination)

    )

    SELECT Origin, Destination, Tonnage

    FROM (

    SELECT TOP ((SELECT COUNT(*) FROM CTE1)

    ) Origin, Destination, Tonnage

    FROM CTE a

    WHERE EXISTS (

    SELECT 1

    FROM CTE b

    WHERE b.n < a.n AND b.Origin = a.Origin AND b.Destination = a.Destination)) b

    WHERE Tonnage <> 0

    DROP TABLE #Deadhead

    The rest of the query is the same except for the subquery I introduced as the TOP counter.

    This will not work if you have some records with Origin=Destination (but that could be handled in CTE1 also).


    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

Viewing 15 posts - 1 through 15 (of 21 total)

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