Mam tabelę połączeń, która tworzy relację wiele do wielu między dwiema innymi tabelami. Oto diagram.
Oto moje podstawowe zapytanie SQL.
SELECT `tag_to_url`.url_id, `websites`.url, `tags`.tag_name
FROM `tag_to_url`
INNER JOIN (`websites`,`tags`) ON `websites`.url_id = `tag_to_url`.url_id
AND `tag_to_url`.tag_id = `tags`.tag_id
ORDER BY `tag_to_url`.url_id
To jest wynik tego.
+--------------------+-------------+
| url | tag_name |
+--------------------+-------------+
| google.com | search |
| google.com | e-mail |
| stackexchange.com | q&a |
| stackexchange.com | programming |
| stackexchange.com | database |
+--------------------+-------------+
Te wyniki są w zasadzie tym, czego szukam, chociaż próbowałem zgrupować URL, który nie działa poprawnie. Zapytanie będzie również działać poprawnie, jeśli je uwzględnię WHERE
klauzula.
...
...
WHERE `tags`.tag_name = "database"
+--------------------+-------------+
| url | tag_name |
+--------------------+-------------+
| stackexchange.com | database |
+--------------------+-------------+
Ale kiedy dodam AND
operator do WHERE
warunek, oczekuję tego.
WHERE `tags`.tag_name = "database" AND `tags`.tag_name = "q&a"
+--------------------+-------------+
| url | tag_name |
+--------------------+-------------+
| stackexchange.com | database |
| stackexchange.com | q&a |
+--------------------+-------------+
Dostaję jednak:
MySQL returned an empty result set (i.e. zero rows). (Query took 0.0027 sec)
Próbowałem też dodać warunek w ON
z JOIN
ale wynik był taki sam. Co robię źle, proszę?
EDYTOWAĆ :
Celem tego zapytania jest pobranie jednego lub więcej tagów wraz z listą powiązanych z nimi adresów URL. Muszę mieć możliwość korzystania z wielu AND
operatorów do pobierania tylko tych określonych znaczników. Musi działać jak przepełnienie stosu, gdzie jest pytanie (URL) i wiele tagów dołączonych do niego.
Odpowiedzi:
0 dla odpowiedzi № 1Właściwy sposób użycia AND
OR
w mysql jest
select * from `table` where col1 = "someval" and col2="someval" ;
select * from `table` where col1 = "someval" OR col1="someval" ;
Musisz określić nazwy kolumn w każdym warunku.
Więc musisz mieć zapytanie jako
WHERE `tags`.tag_name = "database" OR `tags`.tag_name "q&a"
Równie dobrze może być równoważne oświadczenie IN
WHERE `tags`.tag_name IN("database","q&a")
EDYCJA: Oto zapytanie, które może wykonać zadanie przy użyciu group_concat
i group by
SELECT
tu.url_id,
w.url,
group_concat(t.tag_name) as tag_name
FROM tag_to_url tu
inner join websites w on w.url_id = tu.url_id
inner join tags t on t.tag_id = tu.tag_id
where t.tag_name in ("database","q&a")
group by w.url
having count(*) = 2
1 dla odpowiedzi nr 2
Musisz użyć OR zamiast AND w klauzuli where, ponieważ szukasz zarówno bazy danych, jak i q & a.
więc gdzie powinien być warunek WHERE
tagi.tag_name = "database" OR "q&a"