hi-
i want to find master records where that master doesn't have a
presence in the join table. for example, if i were doing a restaurant
review web site, and i have users, reviews, and restaurants. i want
to find all restaurants for which a specific user has NOT written a
review.
i tried this:
select distinct restaurants.id from restaurants left join reviews on
restaurants.id = reviews.restaurant_id where (reviews.user_id <> 5 or
review_users is NULL)
but this doesn't work because it finds restaurants where user 5 AND
someone else have reviewed and only eliminates the user 5 row. i want
to find only restaurants that user 5 has not reviewed.
thanks for any help
dino
|
|
0
|
|
|
|
Reply
|
dinodorroco (23)
|
1/31/2010 5:00:46 PM |
|
In article <455bf818-b0e6-4e65-80db-11a840ae2185@v7g2000vbd.googlegroups.com>, "dino d." <dinodorroco@yahoo.com> wrote:
>hi-
>
>i want to find master records where that master doesn't have a
>presence in the join table. for example, if i were doing a restaurant
>review web site, and i have users, reviews, and restaurants. i want
>to find all restaurants for which a specific user has NOT written a
>review.
>
>i tried this:
>
>select distinct restaurants.id from restaurants left join reviews on
>restaurants.id = reviews.restaurant_id where (reviews.user_id <> 5 or
>review_users is NULL)
>
>but this doesn't work because it finds restaurants where user 5 AND
>someone else have reviewed and only eliminates the user 5 row.
Right, because you're asking for restaurants that have been reviewed by
somebody other than user 5, or have been reviewed by nobody. That's not the
same as asking for restaurants that have not been reviewed by user 5.
> i want
>to find only restaurants that user 5 has not reviewed.
Then you need to ask for restaurants that user 5 has not reviewed. Change your
WHERE clause to
WHERE restaurant.id NOT IN
(SELECT restaurant_id FROM reviews WHERE user_id = 5)
|
|
0
|
|
|
|
Reply
|
spambait
|
1/31/2010 5:15:54 PM
|
|
thanks for the reply- is there any way to do this without a subquery?
this will get very expensive very quickly, right?
On Jan 31, 12:15=A0pm, spamb...@milmac.com (Doug Miller) wrote:
> In article <455bf818-b0e6-4e65-80db-11a840ae2...@v7g2000vbd.googlegroups.=
com>, "dino d." <dinodorr...@yahoo.com> wrote:
>
>
>
> >hi-
>
> >i want to find master records where that master doesn't have a
> >presence in the join table. =A0for example, if i were doing a restaurant
> >review web site, and i have users, reviews, and restaurants. =A0i want
> >to find all restaurants for which a specific user has NOT written a
> >review.
>
> >i tried this:
>
> >select distinct restaurants.id =A0from restaurants left join reviews on
> >restaurants.id =3D reviews.restaurant_id where (reviews.user_id <> 5 or
> >review_users is NULL)
>
> >but this doesn't work because it finds restaurants where user 5 AND
> >someone else have reviewed and only eliminates the user 5 row.
>
> Right, because you're asking for restaurants that have been reviewed by
> somebody other than user 5, or have been reviewed by nobody. That's not t=
he
> same as asking for restaurants that have not been reviewed by user 5.
>
> > i want
> >to find only restaurants that user 5 =A0has not reviewed.
>
> Then you need to ask for restaurants that user 5 has not reviewed. Change=
your
> WHERE clause to
>
> WHERE restaurant.id NOT IN
> (SELECT restaurant_id FROM reviews WHERE user_id =3D 5)
|
|
0
|
|
|
|
Reply
|
dino
|
1/31/2010 5:33:45 PM
|
|
In article <9b85347f-c52e-4352-a3bc-a809b7f2db74@f11g2000yqm.googlegroups.com>, "dino d." <dinodorroco@yahoo.com> wrote:
[Top-posting corrected -- please don't do that]
>
>On Jan 31, 12:15=A0pm, spamb...@milmac.com (Doug Miller) wrote:
>> In article <455bf818-b0e6-4e65-80db-11a840ae2...@v7g2000vbd.googlegroups.=
>com>, "dino d." <dinodorr...@yahoo.com> wrote:
>> >i want to find master records where that master doesn't have a
>> >presence in the join table. =A0for example, if i were doing a restaurant
>> >review web site, and i have users, reviews, and restaurants. =A0i want
>> >to find all restaurants for which a specific user has NOT written a
>> >review.
>>
>> >i tried this:
>>
>> >select distinct restaurants.id =A0from restaurants left join reviews on
>> >restaurants.id =3D reviews.restaurant_id where (reviews.user_id <> 5 or
>> >review_users is NULL)
>>
>> >but this doesn't work because it finds restaurants where user 5 AND
>> >someone else have reviewed and only eliminates the user 5 row.
>>
>> Right, because you're asking for restaurants that have been reviewed by
>> somebody other than user 5, or have been reviewed by nobody. That's not the
>> same as asking for restaurants that have not been reviewed by user 5.
>>
>> > i want
>> >to find only restaurants that user 5 has not reviewed.
>>
>> Then you need to ask for restaurants that user 5 has not reviewed. Change your
>> WHERE clause to
>>
>> WHERE restaurant.id NOT IN
>> (SELECT restaurant_id FROM reviews WHERE user_id = 5)
>
>thanks for the reply- is there any way to do this without a subquery?
No.
>this will get very expensive very quickly, right?
No, not if you have your tables indexed properly. With indexes on
reviews.user_id, reviews.restaurant_id, and restaurant.id, this will be very
fast.
|
|
0
|
|
|
|
Reply
|
spambait
|
1/31/2010 6:02:44 PM
|
|
Doug Miller:
>In article
><9b85347f-c52e-4352-a3bc-a809b7f2db74@f11g2000yqm.googlegroups.com>,
>"dino d." <dinodorroco@yahoo.com> wrote:
>>> > i want
>>> >to find only restaurants that user 5 has not reviewed.
>>>
>>> Then you need to ask for restaurants that user 5 has not
>>>reviewed. Change your WHERE clause to
>>>
>>> WHERE restaurant.id NOT IN
>>> (SELECT restaurant_id FROM reviews WHERE user_id = 5)
>>
>>thanks for the reply- is there any way to do this without a
>>subquery?
>
>No.
I'll give it a try anyway: would this give the same result?
select restaurants.id from restaurants
left join reviews
on restaurants.id = reviews.restaurant_id
and reviews.user_id = 5
group by restaurants.id
having count(reviews.id)=0
--
Erick
|
|
0
|
|
|
|
Reply
|
Erick
|
1/31/2010 6:17:16 PM
|
|
On Jan 31, 5:15=A0pm, spamb...@milmac.com (Doug Miller) wrote:
> In article <455bf818-b0e6-4e65-80db-11a840ae2...@v7g2000vbd.googlegroups.=
com>, "dino d." <dinodorr...@yahoo.com> wrote:
>
>
>
>
>
> >hi-
>
> >i want to find master records where that master doesn't have a
> >presence in the join table. =A0for example, if i were doing a restaurant
> >review web site, and i have users, reviews, and restaurants. =A0i want
> >to find all restaurants for which a specific user has NOT written a
> >review.
>
> >i tried this:
>
> >select distinct restaurants.id =A0from restaurants left join reviews on
> >restaurants.id =3D reviews.restaurant_id where (reviews.user_id <> 5 or
> >review_users is NULL)
>
> >but this doesn't work because it finds restaurants where user 5 AND
> >someone else have reviewed and only eliminates the user 5 row.
>
> Right, because you're asking for restaurants that have been reviewed by
> somebody other than user 5, or have been reviewed by nobody. That's not t=
he
> same as asking for restaurants that have not been reviewed by user 5.
>
> > i want
> >to find only restaurants that user 5 =A0has not reviewed.
>
> Then you need to ask for restaurants that user 5 has not reviewed. Change=
your
> WHERE clause to
>
> WHERE restaurant.id NOT IN
> (SELECT restaurant_id FROM reviews WHERE user_id =3D 5)
This is a good candidate for the EXISTS predicate:
WHERE NOT EXISTS (SELECT * FROM reviews WHERE restaurant.id =3D
reviews.restaurant_id AND reviews.user_id =3D 5)
It can also be done using a self join on the reviews table.
|
|
0
|
|
|
|
Reply
|
Captain
|
1/31/2010 10:22:42 PM
|
|
Captain Paralytic:
>On Jan 31, 5:15�pm, spamb...@milmac.com (Doug Miller) wrote:
>> In article
>> WHERE restaurant.id NOT IN
>> (SELECT restaurant_id FROM reviews WHERE user_id = 5)
>
>This is a good candidate for the EXISTS predicate:
>
>WHERE NOT EXISTS (SELECT * FROM reviews WHERE restaurant.id =
>reviews.restaurant_id AND reviews.user_id = 5)
Sounds good.
Is this "NOT EXISTS" more or less an equivalent of "NOT IN" as per
Doug's example?
>
>It can also be done using a self join on the reviews table.
It can. But as soon as there are more reviews than restaurants (which
may be assumed) this appears to become a bit slower than my proposal,
because the (self) JOIN would result in a larger intermediate result
set.
Is that correct?
--
Erick
|
|
0
|
|
|
|
Reply
|
Erick
|
2/1/2010 7:03:05 AM
|
|
On 1 Feb, 07:03, "Erick T. Barkhuis" <erick.use-...@ardane.c.o.m>
wrote:
> Captain Paralytic:
>
> >On Jan 31, 5:15=A0pm, spamb...@milmac.com (Doug Miller) wrote:
> >> In article
> >> WHERE restaurant.id NOT IN
> >> (SELECT restaurant_id FROM reviews WHERE user_id =3D 5)
>
> >This is a good candidate for the EXISTS predicate:
>
> >WHERE NOT EXISTS (SELECT * FROM reviews WHERE restaurant.id =3D
> >reviews.restaurant_id AND reviews.user_id =3D 5)
>
> Sounds good.
> Is this "NOT EXISTS" more or less an equivalent of "NOT IN" as per
> Doug's example?
I don't think it is. It really depends on how MySQL creates the list
of IDs for use in the IN clause.
If there is a composite index on reviews.restaurant_id +
reviews.user_id (in either order), then this index can be used to get
an instant answer as to whether the instance exists.
However, I would not necessarily expect MySQL to build the list of IDs
for the IN clause as an index (although it may do), hence the only way
to be sure that the ID is not in the list would be to scan the
complete list each time.
> >It can also be done using a self join on the reviews table.
>
> It can. But as soon as there are more reviews than restaurants (which
> may be assumed) this appears to become a bit slower than my proposal,
> because the (self) JOIN would result in a larger intermediate result
> set.
> Is that correct?
Well, it depends on what indexes are available and precisely how the
joins are written. Rememeber that, as with the NOT EXISTS, there will
not necessarily be an "intermediate result set". If I was coding this
using VSAM or ISAM, I would look up each item in the index to see if
it existed and I am pretty sure that that is what MySQL will do.
Not everything is done with an "intermediate result set". The "IN
(SELECT ...)", certainly will produce one, but when indexes are
available for lookups, then there is no need to do anything apart from
look to see if the item exists in the index.
|
|
0
|
|
|
|
Reply
|
Captain
|
2/1/2010 10:31:51 AM
|
|
On Jan 31, 7:17=A0pm, "Erick T. Barkhuis" <erick.use-...@ardane.c.o.m>
wrote:
[...]
> I'll give it a try anyway: would this give the same result?
>
> select =A0restaurants.id =A0from restaurants
> left join =A0 =A0 =A0 reviews
> =A0 =A0 =A0 =A0on =A0 =A0 =A0 restaurants.id =3D reviews.restaurant_id
> =A0 =A0 =A0 and =A0 =A0 =A0 reviews.user_id =3D 5
> group by =A0 =A0 =A0 =A0restaurants.id
> having =A0count(reviews.id)=3D0
>
Another variant is:
select restaurants.id
from restaurants
left join reviews
on restaurants.id =3D reviews.restaurant_id
and reviews.user_id =3D 5
where reviews.id is null
/Lennart
|
|
0
|
|
|
|
Reply
|
Lennart
|
2/1/2010 2:38:16 PM
|
|
|
8 Replies
173 Views
(page loaded in 0.228 seconds)
Similiar Articles: How best to detect duplicate values in a column? - comp.databases ...How best to do it? - Join the table with ... each group, select only when ... to INSERT a new record in the table of answers.) And usually only on the devleopment site, not ... Can a procedure contain only a SELECT statement? - comp.databases ...Some do not need the choice, some are only looking for ... text.pdf How can I select only a column from a table of ... appears only ... left join (this should be a sub select ... A relationship already exits. Do you want to edit the existing ...... relationship, click No." >> I can only join either AssignmentID or EmployeeID, not ... Creating New Record in a Portal; Multiple ... need a many to many relationship: a master ... The nightmare begins... - comp.databases.filemaker... results, select one go-live date, and do a final migration. Do not go back ... they introduced table views. But they stopped at the single record ... I do not even trust the ... Helvetica substitution - comp.text.pdf... in printers' font substitution tables you can only select ... one of the base fonts and always assumed to be present ... synthetic font manufactured form a Multiple Master. CP/M 3 DRI manual under construction - comp.os.cpmIt's not a big deal, it's only cosmetic after all, but it's something I can do (and I'm ... Henk I'll also do a plain version. I tried to choose ... these documents do NOT ... Sampling: What Nyquist Didn't Say, and What to Do About It - comp ...I wrote my Master's thesis in LaTeX, and ... You're building a detector, >not a ... recorder. Right? It records rms ... I not only own copies of the TeXbook, the ... Web-Safe Fonts? - comp.fonts"Those who record history are those ... elements like headings or table cells, or both? Why? Only ... No, _I_ am not going to present them.) The only half-argument found ... [comp.publish.cdrom] CD-Recordable FAQ, Part 1/4 - comp.publish ...Archive-name: cdrom/cd-recordable/part1 Posting-Frequency: monthly Last-modified: 2008/10/09 Version: 2.71 Send corrections and updates to And... improve strlen - comp.lang.asm.x86... lose the optimizations when you do this). > > For the record, I'm not ... As long as you pick and choose the ... such generalized claim, sorry, only one that did present ... Master boot record - Wikipedia, the free encyclopedia... is not usually present on floppy disks or small thumbdrives. The master boot record ... the master boot record will still contain a partition table, but its only ... may choose ... NTFS.com Fixing and repair MBR.Fix MBR.Recover boot record.Recovery.The Master Boot Record contains the Partition Table for the ... our example only part of the MBR has been damaged which does not ... partition table"...) are present or not 7/18/2012 12:18:15 AM
|