Joins on same table

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Chris

    Joins on same table

    I'm having two general problems trying to do a JOIN. I have a table with
    three fields {Code, Date, Amount}. Code+Date is a unique key. I'm trying
    to get a rowset with 1) one row for each unique Code+Date pair, 2) and
    with each row containing, {Code, Amount for Date-A and Amount for
    Date-B}. Basically, I want to create two temp tables with the Amounts for
    a specified Date and then Join them.

    The problems are
    1) I'm trying to do this in SQL-Server 7 with a single stantment, and
    2) If a Code+Date pair doesn't have any Amounts, I'd still like a row
    returned with NULLs.

    Anybody have any wisdom on this??
    Thanks
  • Chris

    #2
    Re: Joins on same table .. solution with Temps

    The following gets me what I want, using Temp tables. I'm just trying to
    figure out how to combine the Selects into a single statment.

    Thanks

    --------------------------------------------------

    --temp with each Code
    Drop Table #T0;
    Select Code
    Into #T0
    From tblSearch
    Order by Code;

    --temp with amounts for 1st date
    Drop Table #T1;
    Select Code, Date, Amount
    Into #T1
    From tblSearch
    Where Date = 20031102
    Order by Code, Date;

    -- amounts for 2nd date
    Drop Table #T2;
    Select Code, Date, Amount
    Into #T2
    From tblSearch
    Where Date = 20031103
    Order by Code, Date;

    --put everything together
    Select Distinct #T0.Code, #T1.Date, #T1.Amount 'd1', #T2.Date, #T2.Amount
    'd2' from #T0
    Left Outer Join #T1
    On #T0.Code = #T1.Code
    Left Outer Join #T2
    On #T0.Code = #T2.Code
    Order By #T0.Code

    Comment

    • Erland Sommarskog

      #3
      Re: Joins on same table

      [posted and mailed, please reply in news]

      Chris (chris@hicom.ne t) writes:[color=blue]
      > I'm having two general problems trying to do a JOIN. I have a table
      > with three fields {Code, Date, Amount}. Code+Date is a unique key.
      > I'm trying to get a rowset with 1) one row for each unique Code+Date
      > pair, 2) and with each row containing, {Code, Amount for Date-A and
      > Amount for Date-B}. Basically, I want to create two temp tables with
      > the Amounts for a specified Date and then Join them.
      >
      > The problems are
      > 1) I'm trying to do this in SQL-Server 7 with a single stantment, and
      > 2) If a Code+Date pair doesn't have any Amounts, I'd still like a row
      > returned with NULLs.[/color]

      Just rewriting the temp-table thing you had with derived tables
      gives:

      SELECT DISTINCT #T0.Code, #T1.Date, #T1.Amount 'd1',
      #T2.Date, #T2.Amount 'd2'
      FROM tblSearch #T0
      LEFT JOIN (SELECT Code, Date, Amount
      FROM tblSearch
      WHERE Date = '20031102') AS #T1
      ON #T0.Code = #T1.Code
      LEFT JOIN (SELECT Code, Date, Amount
      FROM tblSearch
      WHERE Date = '20031103') AS #T2
      ON #T0.Code = #T2.Code
      ORDER BY #T0.Code

      But if I understand this correctly, it seems that you could get away with:

      SELECT Code = coalesce(a.Code , b.Code), a.Date, d1 = a.Amount,
      b.Date, d2 = b.Amount
      FROM tblSearch a
      FULL JOIN tblSearch b ON a.Code = b.Code
      AND a.Date = b.Date
      AND a.Date = '20031102'
      AND b.Date = '20031103'


      All this works on SQL7.

      --
      Erland Sommarskog, SQL Server MVP, sommar@algonet. se

      Books Online for SQL Server SP3 at
      SQL Server 2025 redefines what's possible for enterprise data. With developer-first features and integration with analytics and AI models, SQL Server 2025 accelerates AI innovation using the data you already have.

      Comment

      • louis nguyen

        #4
        Re: Joins on same table .. solution with Temps

        Hi Chris,

        You can replace temp tables with derived tables. Alternatively, as
        the temp tables are selecting from the same table tblSearch, you can
        also re-write the query using CASE. Note I'm using a mssqlserver
        non-standard syntax. I just find it easier to read.

        "Date=CASE when Date = 20031102 then Date else null end"
        instead of
        "CASE when Date = 20031102 then Date else null end as Date"

        SELECT
        Distinct
        Code,
        Date=CASE when Date = 20031102 then Date else null end,
        Amount=CASE when Date = 20031102 then Amount else null end,
        Date=CASE when Date = 20031103 then Date else null end,
        Amount=CASE when Date = 20031103 then Amount else null end,
        FROM tblSearch
        ORDER BY code

        [color=blue]
        > --temp with each Code
        > Drop Table #T0;
        > Select Code
        > Into #T0
        > From tblSearch
        > Order by Code;
        >
        > --temp with amounts for 1st date
        > Drop Table #T1;
        > Select Code, Date, Amount
        > Into #T1
        > From tblSearch
        > Where Date = 20031102
        > Order by Code, Date;
        >
        > -- amounts for 2nd date
        > Drop Table #T2;
        > Select Code, Date, Amount
        > Into #T2
        > From tblSearch
        > Where Date = 20031103
        > Order by Code, Date;
        >
        > --put everything together
        > Select Distinct #T0.Code, #T1.Date, #T1.Amount 'd1', #T2.Date, #T2.Amount
        > 'd2' from #T0
        > Left Outer Join #T1
        > On #T0.Code = #T1.Code
        > Left Outer Join #T2
        > On #T0.Code = #T2.Code
        > Order By #T0.Code[/color]

        Comment

        • Chris

          #5
          Re: Joins on same table

          The derived table approach gets me what I want -- one row per Code.

          It seems that Coalesce doesn't help reduce the normal number of rows from
          the Join.

          Thanks very much for looking for a solution.

          Comment

          • Chris

            #6
            Re: Joins on same table .. solution with Temps

            The derived tables gets both Amounts into the same row, while the Case
            still results in two (Distinct) rows.

            I need to get a better SQL reference -- the book I'm using does not cover
            derived tables.

            Thanks very much.

            Comment

            • louis nguyen

              #7
              Re: Joins on same table .. solution with Temps

              "Chris" <chris@hicom.ne t> wrote in message news:<2bcNb.324 25$G04.6661104@ news4.srv.hcvln y.cv.net>...[color=blue]
              > The derived tables gets both Amounts into the same row, while the Case
              > still results in two (Distinct) rows.
              >
              > I need to get a better SQL reference -- the book I'm using does not cover
              > derived tables.
              >
              > Thanks very much.[/color]

              Use GROUP if you want combine them into the same row. DISTINCT only
              filters the rows.

              SELECT
              Code,
              Date=max(CASE when Date = 20031102 then Date else null end),
              Amount=max(CASE when Date = 20031102 then Amount else null end),
              Date=max(CASE when Date = 20031103 then Date else null end),
              Amount=max(CASE when Date = 20031103 then Amount else null end)
              FROM tblSearch
              GROUP BY code
              ORDER BY code

              Comment

              • Erland Sommarskog

                #8
                Re: Joins on same table

                Chris (chris@hicom.ne t) writes:[color=blue]
                > It seems that Coalesce doesn't help reduce the normal number of rows
                > from the Join.[/color]

                That's right. The coalesce() function takes a list of values as parameters,
                and return the first value in the list that is not NULL. Since the second
                query included a full join, any of a.code and b.code could be NULL, so be
                sure that we had a value here, I used coalesce(a.Code , b.Code).



                --
                Erland Sommarskog, SQL Server MVP, sommar@algonet. se

                Books Online for SQL Server SP3 at
                SQL Server 2025 redefines what's possible for enterprise data. With developer-first features and integration with analytics and AI models, SQL Server 2025 accelerates AI innovation using the data you already have.

                Comment

                • Chris

                  #9
                  Re: Joins on same table .. solution with Temps


                  Excellent!

                  -- Thanks

                  Comment

                  • Erland Sommarskog

                    #10
                    Re: Joins on same table .. solution with Temps

                    louis nguyen (louisducnguyen @hotmail.com) writes:[color=blue]
                    > SELECT
                    > Code,
                    > Date=max(CASE when Date = 20031102 then Date else null end),
                    > Amount=max(CASE when Date = 20031102 then Amount else null end),
                    > Date=max(CASE when Date = 20031103 then Date else null end),
                    > Amount=max(CASE when Date = 20031103 then Amount else null end)
                    > FROM tblSearch
                    > GROUP BY code
                    > ORDER BY code[/color]

                    Note that date literals requires quotes. 20031103 is a number, and
                    attempt to convert it to datetime results in overflow.


                    --
                    Erland Sommarskog, SQL Server MVP, sommar@algonet. se

                    Books Online for SQL Server SP3 at
                    SQL Server 2025 redefines what's possible for enterprise data. With developer-first features and integration with analytics and AI models, SQL Server 2025 accelerates AI innovation using the data you already have.

                    Comment

                    Working...