У меня есть следующая таблица с этими столбцами: the_comment_liked
, user_who_liked
, value
.
Здесь я настроил SQL-fidle.
И это часть запроса, который я использую:
SELECT the_comment_liked,
COUNT(CASE WHEN value = '1' then '1' ELSE NULL END) AS tot_like,
COUNT(CASE WHEN value = '2' then '1' ELSE NULL END) AS tot_dis,
GROUP_CONCAT(user_who_liked) AS user_who_liked
FROM like_dislike_comm
GROUP BY the_comment_liked
Теперь я выполняю проверку PHP
чтобы узнать, понравилось или не понравилось пользователю следующее:
if (strpos($r_com['user_who_liked'] ,$_SESSION["currentUser"]) !== false){//set a variable}
//$_SESSION["currentUser"] (this stores the id of the current logged user)
Если это возвращает true, я устанавливаю класс в переменную, чтобы выделить понравившуюся или не понравившуюся кнопку, проблема в том, что мне также нужно проверить значение, чтобы узнать, нравится это или не нравится, что-то вроде:
if (strpos($r_com['user_who_liked'] ,$_SESSION["currentUser"]) !== false && $r_com['value'] === 1){}
Теперь я могу это сделать, выбрав значение, но это дает мне дубликаты. Как я могу сформировать запрос, чтобы проверить не только идентификатор пользователя, но и значение, подобное или нелюбовь? Или каким другим способом я мог бы выполнить проверку?
Мне нужно, чтобы все было сгруппировано, чтобы я мог отображать общее количество симпатий и антипатий в комментарии, и в то же время мне нужно, чтобы каждый user_who_liked
проверял, является ли value
1
(например) или 2
(не нравится), поэтому я может выделять понравившуюся или не понравившуюся кнопку для каждого комментария, чтобы зарегистрированный пользователь мог видеть, что ему нравится или нет. Я также не уверен, что использование GROUP_CONCAT(user_who_liked)
- правильный подход.
Версия Mysql - 5.7.14
Вы уже знаете, как выполнять условные агрегации (COUNT(CASE..)
). Чтобы узнать value
текущего пользователя за комментарий, вам просто нужно еще одно. Предполагая, что идентификатор текущего пользователя равен 118
, это будет примерно так:
MAX(CASE WHEN user_who_liked = 118 THEN value ELSE NULL END) AS value_of_current_user
Не имеет значения, используете ли вы MAX
или MIN
здесь, так как должно быть только одно значение. Вы даже можете использовать GROUP_CONCAT
.
Обратите внимание, что NULL
по умолчанию для случая ELSE
, поэтому вы можете его опустить:
MAX(CASE WHEN user_who_liked = 118 THEN value END) AS value_of_current_user
Вы также можете записать его немного короче:
MAX(CASE user_who_liked WHEN 118 THEN value END) AS value_of_current_user
Таким образом, ваш последний запрос может быть:
SELECT the_comment_liked,
COUNT(CASE value WHEN 1 then 1 END) AS tot_like,
COUNT(CASE value WHEN 2 then 1 END) AS tot_dis,
GROUP_CONCAT(user_who_liked) AS user_who_liked,
MAX(CASE user_who_liked WHEN 118 THEN value END) AS value_of_current_user
FROM like_dislike_comm
GROUP BY the_comment_liked
Если вы также хотите разбить идентификационный список на users_who_liked
и users_who_disliked
, вы также можете использовать условную агрегацию для GROUP_CONCAT
:
SELECT the_comment_liked,
COUNT(CASE value WHEN 1 then 1 END) AS tot_like,
COUNT(CASE value WHEN 2 then 1 END) AS tot_dis,
GROUP_CONCAT(CASE value WHEN 1 THEN user_who_liked END) AS user_who_liked,
GROUP_CONCAT(CASE value WHEN 2 THEN user_who_liked END) AS user_who_disliked,
MAX(CASE user_who_liked WHEN 118 THEN value END) AS value_of_current_user
FROM like_dislike_comm
GROUP BY the_comment_liked
Если я что-то не понял, каждый раз, когда вы запускаете этот запрос, это может быть только для одного пользователя (один из зарегистрированных).
Если это так, то это довольно неэффективно, чтобы ваш SQL не помог вам больше.
Нижеприведенное решение жестко запрограммировано для пользователя 118. Ваш PHP должен ввести этот параметр, где вы видите 118, ИЛИ, вы можете превратить этот код в хранимую процедуру MySQL, которая принимает пользователя в качестве параметра.
Вывод показывает все комментарии, общее количество понравлений, общее неприятие и то, что голосование за одного пользователя (1 = нравится, 2 = не нравится, нуль = нет голоса).
select
totals.the_comment_liked,
totals.tot_like,
totals.tot_dis,
like_or_dislike.value as this_users_vote
from
(
select
the_comment_liked,
sum(case when value = 1 then 1 else 0 end) as tot_like,
sum(case when value = 2 then 1 else 0 end) as tot_dis
from
like_dislike_comm
group by
the_comment_liked
) as totals
left outer join (
select
the_comment_liked,
value
from
like_dislike_comm
where
/* This value has to be dynamically inserted by your PHP,
OR you can make this a parameter in a stored procedure */
user_who_liked = 118
) as like_or_dislike on
totals.the_comment_liked = like_or_dislike.the_comment_liked
Это возвращает следующий набор результатов (опять же, это жесткий код для пользователя 118):
the_comment_liked tot_like tot_dis this_users_vote
310 0 1 2
311 1 1 1
312 1 2 2
313 1 2 1
314 0 3 2
315 2 1 2
339 1 0 (null)
340 1 0 (null)
341 1 0 (null)
347 1 0 (null)
353 1 0 (null)
360 1 1 2
365 0 1 (null)
366 1 1 (null)
370 1 2 1
378 1 0 (null)
380 1 0 (null)
387 2 0 (null)
388 1 0 (null)
394 1 1 (null)
395 0 1 (null)
426 1 0 (null)
430 2 0 (null)
439 0 1 (null)
value
чтобы узнать, какое из них есть, чтобы я мог «покрасить» кнопку «нравится» или «не нравится» , но поскольку все сгруппировано, я не знаю, как проверить, что сделал пользователь, вошедший в систему (понравился или не понравился)