Unix Technical Forum

SQL Join Problem

This is a discussion on SQL Join Problem within the SQL Server forums, part of the Microsoft SQL Server category; --> I'm having a bit of a SQL problem and I can't figure it out. I have a working solution, ...


Go Back   Unix Technical Forum > Database Server Software > Microsoft SQL Server > SQL Server

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 02-28-2008, 09:01 PM
Thomas Brown
 
Posts: n/a
Default 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 NonCriticalViolations CriticalViolations

5/30/2003 6 2



Here is my SQL and what it returns.

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

select

tblInspections.ReceivedByDate,

tblViolations.Type,

count(tblViolations.Type) as ViolationCount

from

tblinspections

join tblViolations on tblInspections.ID = tblviolations.InspID

where tblInspections.iestabid = 100

group by

tblViolations.Type,

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

count(CritVios.Type) as CritViolationCount

from

tblInspections

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

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


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 02-28-2008, 09:01 PM
Thomas Brown
 
Posts: n/a
Default Re: SQL Join Problem

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

select
tblInspections.ReceivedByDate,
(select count(tblViolations.id) from tblViolations
where tblViolations.Type = 0 and tblViolations.inspID =
tblInspections.ID) as NonCriticals,
(select count(tblViolations.id) from tblViolations
where tblViolations.type = 1 and tblViolations.inspID =
tblInspections.ID) as Criticals
from tblInspections




"Thomas Brown" <thom@semo.net> wrote in message
news:1034m26fbcvou65@corp.supernews.com...
> 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 NonCriticalViolations CriticalViolations
>
> 5/30/2003 6 2
>
>
>
> Here is my SQL and what it returns.
>
> --------------------------------------------------------------------------

--
> ----------------------------------------------------------------
>
> select
>
> tblInspections.ReceivedByDate,
>
> tblViolations.Type,
>
> count(tblViolations.Type) as ViolationCount
>
> from
>
> tblinspections
>
> join tblViolations on tblInspections.ID = tblviolations.InspID
>
> where tblInspections.iestabid = 100
>
> group by
>
> tblViolations.Type,
>
> 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 NCritViolationCount,
>
> count(CritVios.Type) as CritViolationCount
>
> from
>
> tblInspections
>
> join tblViolations as NCritVios on NCritVios.Type = 0 and
> tblInspections.ID = NCritVios.InspID
>
> 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
>
>



Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 02-28-2008, 09:02 PM
Joe Celko
 
Posts: n/a
Default 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.

>> I've got two tables, inspections and violations. Each inspection

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_TIMESTAMP NOT NULL,
..);

CREATE TABLE Citations
(insp_id INTEGER NOT NULL
REFERENCES Inspections(insp_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)),
..);

>> What I want is to get a list of inspections by establishment_id with

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_type = 1 THEN 1 ELSE 0 END)
AS critical,
SUM (CASE WHEN C1.violation_type = 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!
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 02-28-2008, 09:02 PM
Erland Sommarskog
 
Posts: n/a
Default Re: SQL Join Problem

[posted and mailed, please reply in news]

Thomas Brown (thom@semo.net) writes:
> select tblInspections.ReceivedByDate,
> tblViolations.Type,
> count(tblViolations.Type) as ViolationCount
> from tblinspections
> join tblViolations on tblInspections.ID = tblviolations.InspID
> where tblInspections.iestabid = 100
> group by tblViolations.Type,
> 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.


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

select i.ReceivedByDate,
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.ReceivedByDate


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

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 02-28-2008, 09:02 PM
Joe Celko
 
Posts: n/a
Default 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!
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Forum Jump


All times are GMT. The time now is 10:31 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com