Oczywiście jest "nieco" bardziej skomplikowane, ale do tego się sprowadza
CREATE TABLE `product_tag` (
`tid` int(10) UNSIGNED NOT NULL DEFAULT '',
`pid` int(10) UNSIGNED NOT NULL DEFAULT '',
KEY `pid` (`pid`),
KEY `tid` (`tid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `product` (
`pid` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`status` int(2) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`pid`),
KEY `search` (`pid`,`status`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
Powycinałem kolumny nie wykorzystywane w zapytaniu, żeby bałaganu nie wprowadzać
SELECT p.*, COUNT(t.tid) AS matches FROM `product` p
INNER JOIN `product_tag` t ON p.pid=t.pid WHERE ( (`tid` IN (val1, val2, val3,..)) AND (p.status>=jakis_status))
GROUP BY t.pid ORDER BY matches DESC, p.STATUS ASC, p.pid DESC LIMIT 0, 10
Sortowanie po dowolnych 2 z tych 3 działa - nie ma problemu status+pid, matches+status, matches+pid, wszystkie trzy niestety już nie.