PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.databases.mysql > Storing tags / array
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Storing tags / array

Réponse
 
LinkBack Outils de la discussion
Vieux 31/12/2007, 06h29   #1
herbasher
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Storing tags / array

I know there is plenty of info for this, however I'm having some
trouble, and would love if someone could give me some info.

I want to tag objects in an "contacts" table.

I can have a separate table called "tags", and have a 1:n
relationship.

contacts: id, name
tags: contact_id, name

Now my question, how could I possibly select a contact that has both
the tag "Investor" AND "San Francisco"?

OR is easy:

SELECT contacts.name FROM contacts LEFT JOIN tags ON contacts.id =
tags.contact_id WHERE tags.name = "Investor" OR tags.name = "San
Francisco"

But AND does not work in this case:

SELECT contacts.name FROM contacts LEFT JOIN tags ON contacts.id =
tags.contact_id WHERE tags.name = "Investor" AND tags.name = "San
Francisco"


So how would I do a AND? I'd prefer not to do a COUNT/GROUP BY/
HAVING solution (too complicated), is that the only way?



thanks,
Herb
  Réponse avec citation
Vieux 31/12/2007, 07h15   #2
Gordon Burditt
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Storing tags / array

>I know there is plenty of info for this, however I'm having some
>trouble, and would love if someone could give me some info.
>
>I want to tag objects in an "contacts" table.
>
>I can have a separate table called "tags", and have a 1:n
>relationship.
>
>contacts: id, name
>tags: contact_id, name
>
>Now my question, how could I possibly select a contact that has both
>the tag "Investor" AND "San Francisco"?


Do a multi-way join between 'contacts' and N copies of the 'tags' table.
You have to use aliases for this, since you have to refer separately
to different instances of the tags table.

SELECT ...whatever... FROM contacts, tags t1, tags t2 ...

t1 is the tags entry with "Investor".
t2 is the tags entry with "San Francisco".

SELECT contacts.id, contacts.name from contacts, tags t1, tags t2
WHERE t1.contact_id = contacts.id AND t1.name = 'Investor' AND
t2.contact_id = contacts.id AND t2.name = 'San Francisco';
(not tested).

This rapidly gets complicated as looking for N tags requires an N+1-way
join. You can use the same approach with LEFT JOIN and ON clauses to
factor in a tag you DON'T want the results to have.

  Réponse avec citation
Vieux 31/12/2007, 20h01   #3
herbasher
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Storing tags / array

On Dec 30, 11:15 pm, gordonb.10...@burditt.org (Gordon Burditt) wrote:
> >I know there is plenty of info for this, however I'm having some
> >trouble, and would love if someone could give me some info.

>
> >I want to tag objects in an "contacts" table.

>
> >I can have a separate table called "tags", and have a 1:n
> >relationship.

>
> >contacts: id, name
> >tags: contact_id, name

>
> >Now my question, how could I possibly select a contact that has both
> >the tag "Investor" AND "San Francisco"?

>
> Do a multi-way join between 'contacts' and N copies of the 'tags' table.
> You have to use aliases for this, since you have to refer separately
> to different instances of the tags table.
>
> SELECT ...whatever... FROM contacts, tags t1, tags t2 ...
>
> t1 is the tags entry with "Investor".
> t2 is the tags entry with "San Francisco".
>
> SELECT contacts.id, contacts.name from contacts, tags t1, tags t2
> WHERE t1.contact_id = contacts.id AND t1.name = 'Investor' AND
> t2.contact_id = contacts.id AND t2.name = 'San Francisco';
> (not tested).
>
> This rapidly gets complicated as looking for N tags requires an N+1-way
> join. You can use the same approach with LEFT JOIN and ON clauses to
> factor in a tag you DON'T want the results to have.


That's a novel solution, thanks Gordon. Anyone else knows another
way, maybe even easier?
  Réponse avec citation
Vieux 31/12/2007, 22h27   #4
Rik Wasmus
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Storing tags / array

On Mon, 31 Dec 2007 20:01:13 +0100, herbasher <robmnl@gmail.com> wrote:

> On Dec 30, 11:15 pm, gordonb.10...@burditt.org (Gordon Burditt) wrote:
>> >I know there is plenty of info for this, however I'm having some
>> >trouble, and would love if someone could give me some info.

>>
>> >I want to tag objects in an "contacts" table.

>>
>> >I can have a separate table called "tags", and have a 1:n
>> >relationship.

>>
>> >contacts: id, name
>> >tags: contact_id, name

>>
>> >Now my question, how could I possibly select a contact that has both
>> >the tag "Investor" AND "San Francisco"?

>>
>> Do a multi-way join between 'contacts' and N copies of the 'tags' table.
>> You have to use aliases for this, since you have to refer separately
>> to different instances of the tags table.
>>
>> SELECT ...whatever... FROM contacts, tags t1, tags t2 ...
>>
>> t1 is the tags entry with "Investor".
>> t2 is the tags entry with "San Francisco".
>>
>> SELECT contacts.id, contacts.name from contacts, tags t1, tags t2
>> WHERE t1.contact_id = contacts.id AND t1.name = 'Investor' AND
>> t2.contact_id = contacts.id AND t2.name = 'San Francisco';
>> (not tested).
>>
>> This rapidly gets complicated as looking for N tags requires an N+1-way
>> join. You can use the same approach with LEFT JOIN and ON clauses to
>> factor in a tag you DON'T want the results to have.

>
> That's a novel solution, thanks Gordon. Anyone else knows another
> way, maybe even easier?


A dirty hack could be as followed: a combination of contect_id & name in
your tags table MUST be unique for this, 3 is the number here of tags to
match:

SELECT contact_id, COUNT(*) as 'matchcount'
FROM tags
WHERE name IN ('foo','bar','foz')
GROUP BY contact_id
HAVING matchcount = 3

or, for 4 tags:

SELECT contact_id, COUNT(*) as 'matchcount'
FROM tags
WHERE name IN ('foo','bar','foz','baz')
GROUP BY contact_id
HAVING matchcount = 4

It's not a very nice one, and it assumes a lot, however it could work.

--
Rik Wasmus
  Réponse avec citation
Vieux 05/01/2008, 08h23   #5
herbasher
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Storing tags / array

On Dec 31 2007, 2:27 pm, "Rik Wasmus" <luiheidsgoe...@hotmail.com>
wrote:
> On Mon, 31 Dec 2007 20:01:13 +0100, herbasher <rob...@gmail.com> wrote:
> > On Dec 30, 11:15 pm, gordonb.10...@burditt.org (Gordon Burditt) wrote:
> >> >I know there is plenty of info for this, however I'm having some
> >> >trouble, and would love if someone could give me some info.

>
> >> >I want to tag objects in an "contacts" table.

>
> >> >I can have a separate table called "tags", and have a 1:n
> >> >relationship.

>
> >> >contacts: id, name
> >> >tags: contact_id, name

>
> >> >Now my question, how could I possibly select a contact that has both
> >> >the tag "Investor" AND "San Francisco"?

>
> >> Do a multi-way join between 'contacts' and N copies of the 'tags' table.
> >> You have to use aliases for this, since you have to refer separately
> >> to different instances of the tags table.

>
> >> SELECT ...whatever... FROM contacts, tags t1, tags t2 ...

>
> >> t1 is the tags entry with "Investor".
> >> t2 is the tags entry with "San Francisco".

>
> >> SELECT contacts.id, contacts.name from contacts, tags t1, tags t2
> >> WHERE t1.contact_id = contacts.id AND t1.name = 'Investor' AND
> >> t2.contact_id = contacts.id AND t2.name = 'San Francisco';
> >> (not tested).

>
> >> This rapidly gets complicated as looking for N tags requires an N+1-way
> >> join. You can use the same approach with LEFT JOIN and ON clauses to
> >> factor in a tag you DON'T want the results to have.

>
> > That's a novel solution, thanks Gordon. Anyone else knows another
> > way, maybe even easier?

>
> A dirty hack could be as followed: a combination of contect_id & name in
> your tags table MUST be unique for this, 3 is the number here of tags to
> match:
>
> SELECT contact_id, COUNT(*) as 'matchcount'
> FROM tags
> WHERE name IN ('foo','bar','foz')
> GROUP BY contact_id
> HAVING matchcount = 3
>
> or, for 4 tags:
>
> SELECT contact_id, COUNT(*) as 'matchcount'
> FROM tags
> WHERE name IN ('foo','bar','foz','baz')
> GROUP BY contact_id
> HAVING matchcount = 4
>
> It's not a very nice one, and it assumes a lot, however it could work.
>
> --
> Rik Wasmus


Thanks Rik, I knew that one.

Seems like SQL is really not that perfect for certain situations.

Appreciated,
Rob
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 01h39.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,14992 seconds with 13 queries