SQL Join Problem

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

    SQL Join Problem

    I'm having a bit of a SQL problem and I can't figure it out. I have a
    working solution, but it could be better.



    I've got two tables, tblInspections and tblViolations. Each inspection
    record has an associated establishment id. Each inspection record can have
    multiple violation records associated with it. Each violation can be either
    of type 1 (critical) or 0 (noncritical).



    What I want is to get a list of inspections by establishmentid with a column
    for the count of noncritical violations, and a count of critical violations.



    EG.



    Date NonCriticalViol ations CriticalViolati ons

    5/30/2003 6 2



    Here is my SQL and what it returns.

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

    select

    tblInspections. ReceivedByDate,

    tblViolations.T ype,

    count(tblViolat ions.Type) as ViolationCount

    from

    tblinspections

    join tblViolations on tblInspections. ID = tblviolations.I nspID

    where tblInspections. iestabid = 100

    group by

    tblViolations.T ype,

    tblInspections. ReceivedByDate

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



    and it returns:


    +++++++++++++++ ++++++++

    Date: Type Count

    2003-05-20 0 2

    2003-05-20 1 2

    +++++++++++++++ ++++++++



    I can work with this (because it is correct), but would prefer it all on one
    record.



    Here's what I've tried:

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

    select

    tblInspections. ReceivedByDate,

    count(NCritVios .Type) as NCritViolationC ount,

    count(CritVios. Type) as CritViolationCo unt

    from

    tblInspections

    join tblViolations as NCritVios on NCritVios.Type = 0 and
    tblInspections. ID = NCritVios.InspI D

    join tblViolations as CritVios on CritVios.Type = 1 and
    tblInspections. ID = CritVios.InspID

    where

    tblInspections. iestabid = 100

    group by

    tblInspections. ReceivedByDate, NCritVios.Type

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



    and it retuns:

    +++++++++++++++ ++++++++

    Date: NCrit Crit

    2003-05-20 4 4

    +++++++++++++++ ++++++++



    which is not correct.



    Note that without the second count in the select and without the second
    join, it works (counts ncrits correctly). It's that second join.



    Any ideas?



    Thanks.



    Thom


  • Thomas Brown

    #2
    Re: SQL Join Problem

    Here's the solution I found, if anybody cares.

    select
    tblInspections. ReceivedByDate,
    (select count(tblViolat ions.id) from tblViolations
    where tblViolations.T ype = 0 and tblViolations.i nspID =
    tblInspections. ID) as NonCriticals,
    (select count(tblViolat ions.id) from tblViolations
    where tblViolations.t ype = 1 and tblViolations.i nspID =
    tblInspections. ID) as Criticals
    from tblInspections




    "Thomas Brown" <thom@semo.ne t> wrote in message
    news:1034m26fbc vou65@corp.supe rnews.com...[color=blue]
    > I'm having a bit of a SQL problem and I can't figure it out. I have a
    > working solution, but it could be better.
    >
    >
    >
    > I've got two tables, tblInspections and tblViolations. Each inspection
    > record has an associated establishment id. Each inspection record can[/color]
    have[color=blue]
    > multiple violation records associated with it. Each violation can be[/color]
    either[color=blue]
    > of type 1 (critical) or 0 (noncritical).
    >
    >
    >
    > What I want is to get a list of inspections by establishmentid with a[/color]
    column[color=blue]
    > for the count of noncritical violations, and a count of critical[/color]
    violations.[color=blue]
    >
    >
    >
    > EG.
    >
    >
    >
    > Date NonCriticalViol ations CriticalViolati ons
    >
    > 5/30/2003 6 2
    >
    >
    >
    > Here is my SQL and what it returns.
    >
    > --------------------------------------------------------------------------[/color]
    --[color=blue]
    > ----------------------------------------------------------------
    >
    > select
    >
    > tblInspections. ReceivedByDate,
    >
    > tblViolations.T ype,
    >
    > count(tblViolat ions.Type) as ViolationCount
    >
    > from
    >
    > tblinspections
    >
    > join tblViolations on tblInspections. ID = tblviolations.I nspID
    >
    > where tblInspections. iestabid = 100
    >
    > group by
    >
    > tblViolations.T ype,
    >
    > tblInspections. ReceivedByDate
    >
    > --------------------------------------------------------------------------[/color]
    --[color=blue]
    > ----------------------------------------------------------------
    >
    >
    >
    > and it returns:
    >
    >
    > +++++++++++++++ ++++++++
    >
    > Date: Type Count
    >
    > 2003-05-20 0 2
    >
    > 2003-05-20 1 2
    >
    > +++++++++++++++ ++++++++
    >
    >
    >
    > I can work with this (because it is correct), but would prefer it all on[/color]
    one[color=blue]
    > record.
    >
    >
    >
    > Here's what I've tried:
    >
    > --------------------------------------------------------------------------[/color]
    --[color=blue]
    > ----------------------------------------------------------------
    >
    > select
    >
    > tblInspections. ReceivedByDate,
    >
    > count(NCritVios .Type) as NCritViolationC ount,
    >
    > count(CritVios. Type) as CritViolationCo unt
    >
    > from
    >
    > tblInspections
    >
    > join tblViolations as NCritVios on NCritVios.Type = 0 and
    > tblInspections. ID = NCritVios.InspI D
    >
    > join tblViolations as CritVios on CritVios.Type = 1 and
    > tblInspections. ID = CritVios.InspID
    >
    > where
    >
    > tblInspections. iestabid = 100
    >
    > group by
    >
    > tblInspections. ReceivedByDate, NCritVios.Type
    >
    > --------------------------------------------------------------------------[/color]
    --[color=blue]
    > ----------------------------------------------------------------
    >
    >
    >
    > and it retuns:
    >
    > +++++++++++++++ ++++++++
    >
    > Date: NCrit Crit
    >
    > 2003-05-20 4 4
    >
    > +++++++++++++++ ++++++++
    >
    >
    >
    > which is not correct.
    >
    >
    >
    > Note that without the second count in the select and without the second
    > join, it works (counts ncrits correctly). It's that second join.
    >
    >
    >
    > Any ideas?
    >
    >
    >
    > Thanks.
    >
    >
    >
    > Thom
    >
    >[/color]


    Comment

    • Joe Celko

      #3
      Re: SQL Join Problem

      Please post DDL, so that people do not have to guess what the keys,
      constraints, Declarative Referential Integrity, datatypes, etc. in your
      schema are. Does your boss often ask you to program without this
      information?

      Plese read ISO-11179 so you'll know why not ot put that silly "tbl-"
      prefix on table names. That is, unless this database deals furniture
      inspections, which is what you are saying in ISO terms.
      [color=blue][color=green]
      >> I've got two tables, inspections and violations. Each inspection[/color][/color]
      record [sic] has an associated establishment id. Each inspection record
      [sic] can have multiple violation records [sic] associated with it. Each
      violation can be either of type 1 (critical) OR 0 (non-critical). <<

      You have all the classic newbie design flaws and misconceptions. Rows
      are not records; fields are not columns; tables are not files. A data
      element does not change its name because of the table it appears in.
      There is no "Magical, Global, one-size-fits-all id" -- to be is to be
      something in particular and to be a general, vague nothing in particular
      is to be nothing. DATE is a reserved word in Standard SQL as well as
      too vague to a data element name. And I am almost willing to bet that
      you are using IDENTITY as the key to tables, completing the list of
      Newbie design errors.

      Of course your inspection tickets do have a check digit or other
      built-in validation. You did include DRI and DRI actions (a major
      reason talbes are not files). To my mind, a violation is the situation
      that appears on a citation; a citation is issued for a violation found
      in an inspection at a particular establishment. Is this what you meant
      to post?

      CREATE TABLE Inspections
      (insp_id INTEGER NOT NULL PRIMARY KEY
      CHECK (<< validation rule >>),
      estab_id INTEGER NOT NULL
      REFERENCES Establishments (estab_id),
      receivedbydate DATETIME DEFAULT CURRENT_TIMESTA MP NOT NULL,
      ..);

      CREATE TABLE Citations
      (insp_id INTEGER NOT NULL
      REFERENCES Inspections(ins p_id)
      ON DELETE CASCADE
      ON UPDATE CASCADE,
      violation_code INTEGER NOT NULL
      REFERENCES Violations (violation_code )
      ON DELETE CASCADE
      ON UPDATE CASCADE,
      violation_type INTEGER NOT NULL
      CHECK (violation_type IN (0, 1)),
      ..);
      [color=blue][color=green]
      >> What I want is to get a list of inspections by establishment_i d with[/color][/color]
      a column for the count of non-critical violations, and a count of
      critical violations. <<

      You ask for it by establishment, then show it by date! Kinda like the
      joke about "line up alphabetically by height!" -- I'll do the written
      version of the spec:

      SELECT I1.estab_id,
      SUM (CASE WHEN C1.violation_ty pe = 1 THEN 1 ELSE 0 END)
      AS critical,
      SUM (CASE WHEN C1.violation_ty pe = 0 THEN 1 ELSE 0 END)
      AS non_critical
      FROM Citations AS C1, Inspections AS I1
      WHERE C1.insp_id = I1.insp_id
      GROUP BY I1.I1.estab_id;

      I am not sure if a violation type ought to be in the violations, or if
      the same violation can be deemed to be critical/non-critical on each
      citation (example: violation 1010 = "uncovered food container"; critical
      when food is 3 day old oysters, non-critical when food is cheese). I
      took the latter assumption and let each inspecotr make a judgement call.

      --CELKO--


      *** Sent via Developersdex http://www.developersdex.com ***
      Don't just participate in USENET...get rewarded for it!

      Comment

      • Erland Sommarskog

        #4
        Re: SQL Join Problem

        [posted and mailed, please reply in news]

        Thomas Brown (thom@semo.net) writes:[color=blue]
        > select tblInspections. ReceivedByDate,
        > tblViolations.T ype,
        > count(tblViolat ions.Type) as ViolationCount
        > from tblinspections
        > join tblViolations on tblInspections. ID = tblviolations.I nspID
        > where tblInspections. iestabid = 100
        > group by tblViolations.T ype,
        > tblInspections. ReceivedByDate
        >
        > and it returns:
        >
        > Date: Type Count
        > 2003-05-20 0 2
        > 2003-05-20 1 2
        >
        > I can work with this (because it is correct), but would prefer it all on
        > one record.[/color]

        The same solution as Joe Celko, just not buried among his standard
        diatribe:

        select i.ReceivedByDat e,
        SUM (CASE i.Type WHEN 0 THEN 1 ELSE 0 END) AS NonCritCnt
        SUM (CASE i.Type WHEN 1 THEN 1 ELSE 0 END) AS CritCnt
        from tblinspections i
        join tblViolations v on i.ID = v.InspID
        where i.iestabid = 100
        group by i.ReceivedByDat e


        --
        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

        • Joe Celko

          #5
          Re: SQL Join Problem

          >> The same solution as Joe Celko, just not buried among his standard
          diatribe: <<

          That was a hand-made, custom diatribe!

          --CELKO--
          =============== ============
          Please post DDL, so that people do not have to guess what the keys,
          constraints, Declarative Referential Integrity, datatypes, etc. in your
          schema are.

          *** Sent via Developersdex http://www.developersdex.com ***
          Don't just participate in USENET...get rewarded for it!

          Comment

          Working...