MySQL Left Join Subselect - PullRequest
       7

MySQL Left Join Subselect

5 голосов
/ 22 сентября 2011

У меня есть простая таблица языков / идентификаторов шаблонов:

язык | шаблон

ru, t1
en, t1
ау, т2
ge, t3
en, t1
ge, t2
ge, t3

Шаблон всегда либо t1, t2, либо t3. Всего есть 3 языка: en, au, ge.

В таблице содержится намного больше информации, я просто показываю, что имеет отношение к этому вопросу, я буду использовать данные для построения графиков, и поэтому мне потребуется их возврат в следующем формате:

ru, t1, 3
en, t2, 0
en, t3, 0
ау, t1, 0 ​​
ау, т2, 1
ау, t3, 0
ge, t1, 0 ​​
ge, t2, 1
ge, t3, 2

Считает, сколько шаблонов встречается на каждом языке. Но проблема в том, что я возвращаю нулевой счет, если в таблице нет идентификаторов шаблонов для этого языка.

Я думал, что понадобится какой-то левый субсэмпл для выбора идентификатора шаблона, чтобы убедиться, что 3 идентификатора шаблона возвращены для каждого языка?

Ответы [ 3 ]

6 голосов
/ 23 сентября 2011

Возможно, есть лучший способ сделать это, и я не тестировал его в MySQL, но в SQL Server 2005 работает следующее:

Select a.language, b.template, count (c.template) as combo_count
from
(select distinct language from tablename) as a
inner join (select distinct template from tablename) as b on 1 < 2 /* this could be cross join, same thing. */
left outer join tablename c on c.language = a.language and c.template = b.template
group by a.language, b.template
order by 1, 2

Вот результаты с вашими примерами данных:

au  t1  0
au  t2  1
au  t3  0
en  t1  3
en  t2  0
en  t3  0
ge  t1  0
ge  t2  1
ge  t3  2
0 голосов
/ 23 сентября 2011

Вам нужны две таблицы, в которых перечислены возможные значения языка и шаблона.

CREATE TABLE language (...) AS SELECT DISTINCT language FROM your_table;
CREATE TABLE template (...) AS SELECT DISTINCT template FROM your_table;

Затем вы можете сделать что-то вроде этого:

SELECT l.language, t.template, SUM(CASE WHEN yours.language IS NULL THEN 0 ELSE 1 END) count
FROM language l CROSS JOIN template t
LEFT OUTER JOIN your_table yours ON l.language = yours.language AND t.template = yours.template
GROUP BY l.language, t.template;
0 голосов
/ 22 сентября 2011
  Select a.language, a.template, Count(*) count
  From (Select Distinct language, template From table) a
     Left Join table b
         On b.language = a.language
             And b.template = b.template
  Group By a.language, a.template
...