views:

40

answers:

3

I have the following tables: Orders, Notes, Permits

The following columns are in each table:

Orders = ID
Notes = ID, RelatedID, Note, Timestamp
Permits = ID, OrderId

I have the following query

SELECT o.id
     , op.id
     , n.timestamp
  FROM [tblOrders] o
INNER JOIN [tblNotes] n ON n.[RelatedID] = o.[ID]
INNER JOIN [tblPermits] op ON o.[id] = op.[OrderID]
     WHERE n.[Text] LIKE 'Line item is created%'

An order has 1 to many permits and a order has 1 to many notes

The problem here is that the notes relate to the order and not the individual permit so when you join o.id with n.relatedID if there is more that 1 permit in an order it will actually show 4 records instead of 2 since it joins twice for each permit since the orderID is the same. How can I get this to only return 2 records?

A: 

One way would be

SELECT DISTINCT
o.id
,op.id
.....
....
SQLMenace
Sorry forgot to add that I needed the timestamp as well which is different between the 2 notes so would this still work? I tried select distinct but it still did the same thing...
No, in that case see OMG Ponies' answer
SQLMenace
+4  A: 

The issue is using JOINs risks duplication in the resultset because there'll be a record for each supporting record in the tblnotes. My first recommendation is to re-write so you aren't using a JOIN:

Using EXISTS:

SELECT o.id,
       p.id
  FROM tblorders o
  JOIN tblpermits p ON p.orderid = o.id
 WHERE EXISTS(SELECT NULL
                FROM tblnotes n 
               WHERE n.[Text] LIKE 'Line item is created%'
                 AND n.relatedid = o.id)

Using IN:

SELECT o.id,
       p.id
  FROM tblorders o
  JOIN tblpermits p ON p.orderid = o.id
 WHERE o.id IN (SELECT n.relatedid
                  FROM tblnotes n 
                WHERE n.[Text] LIKE 'Line item is created%')
OMG Ponies
+1 For the exists :). I like exists way better. It should outperform and I also find it more readable (that of course is an opinion but still).
Joni
@Joni: Agreed - EXISTS is also more accommodating, most databases don't support tuples (MySQL only one to my knowledge) but you can compare tuples using EXISTS.
OMG Ponies
A: 
SELECT  o.id ,op.id
FROM    [tblOrders] o
JOIN    [tblPermits] op
ON      op.[OrderID] = o.[id]
WHERE   o.id IN
        (
        SELECT  n.[RelatedID]
        FROM    tblNotes n
        WHERE   n.[Text] LIKE 'Line item is created%'
        )
Quassnoi