13 805
правок
Изменения
→SQL
Есть таблица-отношение <tt>'''tag_image'''</tt> с двумя полями «ID тега» (<tt>'''ti_tag'''</tt>) и «ID изображения» (<tt>'''ti_image'''</tt>). Каждая строчка означает, что фотография с соответствующим ID имеет соответствующий тег.
<code-sql>SELECT DISTINCT tp_tag1CREATE TABLE tag_pair ASFROM (SELECT DISTINCT t1.ti_tag tp_tag1, IFNULL(t2.ti_tag ,0) tp_tag2 FROM tag_image t1 LEFT JOIN tag_image t2 ON t2.ti_image=t1.ti_image AND t2.ti_tag!=t1.ti_tag) tag_pairJOIN (SELECT t1.ti_tag tpi_tag1, t1.ti_image tpi_image, t2.ti_tag tpi_tag2 FROM tag_image t1 LEFT JOIN tag_image t2 ON t2.ti_image=t1.ti_image AND t2.ti_tag!=t1.ti_tag) tag_pair_imageON tpi_tag1=tp_tag1 AND (tpi_tag2!=tp_tag2 OR tp_tag2 IS NULL)</code-sql>
<code-sql>SELECT DISTINCT tp_tag1 FROM tag_pair
LEFT JOIN tag_pair_imagetag_image t1 ON tpi_tag1tp_tag2!=tp_tag1 0 AND (tpi_tag2t1.ti_tag=tp_tag1LEFT JOIN tag_image t2 ON tp_tag2!=0 AND t2.ti_image=t1.ti_image AND t2.ti_tag=tp_tag2 OR tp_tag2 WHERE t2.ti_tag IS NULL)
UNION
SELECT DISTINCT ti_tag t1.tp_tag1 FROM tag_image tag_pair t1LEFT JOIN tag_pair t2 ON t2.tp_tag1=t1.tp_tag1 AND t2.tp_tag2!=t1.tp_tag2LEFT JOIN tag_pair t3 ON t3.tp_tag1=t1.tp_tag2 AND t2.tp_tag2!=t1.tp_tag1WHERE ti_tag NOT IN (t2.tp_tag1 IS NULL AND t3.tp_tag1 IS NULL</code-sql> При использовании MySQL здесь мы наталкиваемся на феномен выполнения UNION - каждый запрос по отдельности выполняется меньше сотых долей секунды, а объединённый запрос - почти полсекунды. Поэтому представляем оптимизированный вариант: <code-sql>SELECT DISTINCT t0.tp_tag1 FROM tag_pairt0 LEFT JOIN tag_image h1 t1 ON h1tp_tag2!=0 AND t1.ti_tag IN (=tp_tag1, tp_tag2) LEFT JOIN tag_image n1 t2 ON n1tp_tag2!=0 AND t2.ti_image=h1t1.ti_image AND n1t2.ti_tag != h1.ti_tag AND n1.ti_tag IN (tp_tag1, tp_tag2) WHERE n1tp_tag2=0 OR t2.ti_tag IS NULLORNOT EXISTS (SELECT * FROM tag_pair t3 WHERE t3.tp_tag1=t0.tp_tag1 AND t3.tp_tag2!=t0.tp_tag2 OR t3.tp_tag1=t0.tp_tag2 AND t3.tp_tag2!=t0.tp_tag1)</code-sql>
== 3D-облака тегов ==