MySQL: порядок, когда значения нет в таблице

#mysql

#mysql

Вопрос:

Я работаю над проблемой, когда у меня есть две таблицы, первая из которых выглядит так:

 id | value
1    d
2    e
3    s
4    g
  

и еще один подобный

 value
d
e
e
s
s
  

и мне нужно упорядочить их в соответствии с количеством раз, когда они встречаются во второй таблице, чтобы e было первым, поскольку оно встречается 2 раза и опережает s в алфавитном порядке, а затем d. Таким образом, конечный результат должен быть примерно таким

 id | value
2    e
3    s
1    d
4    g
  

В настоящее время у меня есть это, которое делает почти именно то, что я хочу

 SELECT table1.id, ordering.count
FROM table1, 
    (SELECT value, COUNT(*) AS count 
     FROM table2 
     GROUP BY value 
     ORDER BY count) AS ordering
WHERE table1.value = ordering.value
ORDER BY ordering.count DESC, table1.value;
  

Единственная проблема заключается в том, что g не отображается в table2, результат — это результат, который я хочу, но без последней строки с g, поскольку он не отображается в таблице упорядочения. Есть ли способ заставить его упорядочить его так, как если бы оно было 0, даже если оно не отображается в списке, или есть какой-либо способ обойти это, используя то, что у меня есть в настоящее время?

Любые указатели приветствуются.

Ответ №1:

Почему бы просто не

 SELECT table1.id, table1.value
FROM table2 
INNER JOIN table2 on table1.value = table2.value
GROUP BY value 
ORDER BY table2.count(*) desc, table1.value desc
  

Комментарии:

1. Интересно, должно ли это быть ЛЕВОЕ СОЕДИНЕНИЕ, и тогда значения таблицы 1 без count = 0 будут просто внизу списка в алфавитном порядке. Не уверен, существуют ли эти случаи, но просто мысль

2. @kbball хороший момент . но я ограничил свой ответ конкретными данными, предложенными OP ..

Ответ №2:

Вам понадобится ЛЕВОЕ СОЕДИНЕНИЕ с вашей сводной таблицей…

 SELECT 
      table1.id, 
      table1.value,
      coalesce( ordering.count, 0 ) as FinalCount
   FROM 
      table1
         LEFT JOIN ( SELECT 
                           value, 
                           COUNT(*) AS count 
                        FROM 
                           table2 
                        GROUP BY 
                           value 
                        ORDER BY count) AS ordering
            ON table1.value = ordering.value
   ORDER BY 
      COALESCE( ordering.count, 0 ) DESC, 
      table1.value
  

Левое соединение говорит, что дайте мне все записи в таблице с левой стороны (ваша таблица 1, как она появляется первой), независимо от совпадения в правой части (ваш подзапрос). Однако, ЕСЛИ он найдет запись в подзапросе, возьмите ее количество. COALESCE() сообщает, что если первое значение равно нулю, то используйте следующее — в данном случае 0, если совпадение не найдено.