MySQL SOL üç NEREDE ifadelere sorunu JOIN

4 Cevap php

Ben etiketi filtreleme fonksiyonları ile kendim için uygulaması alarak bir not inşa ediyorum, ama etiketleri ile notlar kapmak için çalışırken bir sorun yaşıyorum. Etiketi filtre daha iyi ben ne arıyorum daraltmak yardımcı olacaktır, çünkü, değil IN kullanmak VE gerekiyor.

Benim tablo şöyle yapılandırılır:

+ notes          note_id  |  note_title  |  note_uid

+ tags           tag_id   |  tag_title

+ notes_tags     nt_id    |  nt_note_id  |  nt_tag_id

Notes_tags tablo tüm notları 'etiketleri izler.

I am not worried about returning any information about tags, işte bir örnek SOL I only 1 etiketi ile sadece almak notları şu anda kullanıyorum JOIN.

SEÇİN * SOL notları JOIN notes_tags DAN AÇIK note_id = nt_note_id NEREDE note_uid IN (1) VE nt_tag_id = 10

Bu sorgu, bu single tag ile tüm notlarınızı kapmak, mükemmel çalışır. Ancak, böyle bir sorgu kullanarak benim notlar "saptayarak" sorunlar yaşıyorum:

SEÇİN * SOL notları JOIN notes_tags DAN AÇIK note_id = nt_note_id NEREDE note_uid IN (1) VE nt_tag_id = 10 AND nt_tag_id = 11

Ben sözdizimi ile yanlış ne yapıyorum?

4 Cevap

Sonra dış sadece DBMS buna ihtiyacı daha çok çalışması yapıyor katılın, size nt_tag_ids 10 ve 11 nt_tag_ids ile notes_tags ilgili kayıtları gelmiş notları tanımlamak istiyorum varsayarsak.

Bu en bariz çözüm gibi görünüyor:

SELECT * FROM notes n
WHERE EXISTS (SELECT 1 FROM notes_tags nt
   WHERE n.note_id=nt.nt_note_id
   AND nt.nt_tag_id=10)
AND EXISTS (SELECT 1 FROM notes_tags nt2
   WHERE n.note_id=nt2.nt_note_id
   AND nt2.nt_tag_id=11);

Alternatif bir yaklaşım olacaktır:

SELECT n.*, COUNT(*) 
FROM notes n,
notes_tags nt
WHERE n.note_id-nt.nt_note_id
AND nt.nt_tag_id IN (10,11)
GROUP BY .... /* need to add these */
HAVING COUNT(*)=2;

Bu notes_tags tabloda nt_note_id ve nt_tag_id benzersiz bir kısıtlama onların olduğunu varsayar unutmayın.

Ama her ikisi de yukarıda sadece notlar tablodaki verileri döndürecektir. Eğer MN ayrışma tablodan karşılık gelen satırları ayıklamak gerekir:

SELECT *
FROM notes n,
notes_tags nt,
notes_tags nt2
WHERE n.note_id=nt.nt_note_id
AND n.note_id=nt2.note_id
AND nt.nt_note_id=nt2.nt_note_id /* can help the optimizer come up with a faster query */
AND nt.nt_tag_id=10
AND nt2.nt_tag_id=11

Sen biraz daha kolay yanıt ayrıştırma yapmak için çıktı sütunlar ekleyebilirsiniz isteyebilirsiniz.

Bu both 10 ve 11 tag_id yalnızca notları dönecektir.

SELECT notes.*
FROM notes
INNER JOIN notes_tags a ON notes.note_id = a.nt_note_id
                        AND a.nt_tag_id = 10
INNER JOIN notes_tags b ON notes.note_id = b.nt_note_id
                        AND b.nt_tag_id = 11

nt_tag_id = 10 AND nt_tag_id = 11 Bu her zaman false dönecektir

kullanmak nt_tag_id in (10,11) yerine

Her iki etiketleri ihtiyacınız varsa iki kere etiketi tablo katılmadan aşağıda orada cevap olduğunu

Sen kullanarak 'VE' yerine bu kullanımı 'VEYA' nerede böyle fıkra vardır:

SELECT * FROM notes_tags LEFT JOIN notes ON note_id = nt_note_id WHERE note_uid IN ( 1 ) AND (nt_tag_id = 10 OR nt_tag_id = 11)

Daha fazla nt_tag_id eklemek için gidiyoruz eğer sen de böyle IN kullanabilirsiniz.

SELECT * FROM notes_tags LEFT JOIN notes ON note_id = nt_note_id WHERE note_uid IN ( 1 ) AND nt_tag_id IN (10, 11)