MySQL Result - "Group By" удаляет неправильные дубликаты - PullRequest
0 голосов
/ 01 марта 2010

постараюсь описать проблему, с которой я столкнулся:)

Каждая тема / тема на моем форуме представляет собой один диск. Зарегистрированные участники форума используют ряд флажков (один из которых отображается рядом с каждым диском), чтобы отметить каждый диск, который они имеют в своей коллекции. Когда форма $ _POST'ed, она сохраняет информацию в таблице следующим образом:

| user_id - disc_id |
+ -------------------- +
| 2 - 571 |
| 2 - 603 |
| 2 - 4532 |

Когда пользователь в следующий раз просматривает форум, у меня есть флажки и сняты на дисках, которые принадлежат пользователю. Это делается с помощью:

$sql = 'SELECT id, poster, subject, posted, last_post, last_post_id,
last_poster, num_views, num_replies, closed, sticky, moved_to, topicimage,
c.user_id, c.disc_id FROM topics LEFT JOIN collections AS c ON c.disc_id=id
WHERE forum_id='.$id.' ORDER BY sticky DESC;

Вышеприведенный захват всех дисков, которые я затем отображаю, используя следующий (урезанный) код:

$result = $db->query($sql) or error('Unable to fetch topic list '.$sql.'', __FILE__, __LINE__, $db->error());

// If there are topics in this forum
if ($db->num_rows($result))
{

while ($ cur_topic = $ db-> fetch_assoc ($ result)) { // Если вошедший в систему идентификатор пользователя совпадает с текущими дисками user_id (т.е. если этот пользователь владеет этим диском) if ($ cur_topic ['user_id'] == $ pun_user ['id']) { $ read = '
У меня есть это!'; } еще { $ read = '
У меня есть это!'; } } }

Это прекрасно работает, пока второй пользователь не добавит тот же идентификатор диска в свою коллекцию, например:

| user_id - disc_id |
+ -------------------- +
| 2 - 571 |
| 2 - 603 |
| 6 - 571 |

Это приводит к дублированию темы на форуме. Один из них помечен галочкой (потому что он принадлежит мне), другой не помечен, хотя он содержит одну и ту же информацию, такую ​​как идентификатор темы и изображение.

Моей первой мыслью было попытаться добавить GROUP BY c.disc_id в SQL, что успешно удаляет дублирующую тему - однако она удаляет неправильную. Диск, который я отмечал, больше не отображается, оставляя только не отмеченную версию.

Надеюсь, это имеет смысл. Может ли кто-нибудь предложить какие-либо идеи или идеи? Большое спасибо.

Ответы [ 2 ]

0 голосов
/ 01 марта 2010

Я вижу два простых способа решения этой проблемы:

первый:

с двумя запросами вы группируете запрос и секунду, чтобы получить все disc_id, принадлежащие пользователю

второй:

с вашим первым запросом:

if ($db->num_rows($result)) {
  $array = Array();
  while ($cur_topic = $db->fetch_assoc($result)) {
    $id = $cur_topic['disc_id'];
    if (!array_key_exists ($id, $array)) { // allow only result per disc_id
      $array[$id] = $cur_topic;
      $array[$id]['owned'] = false;
    }
    // If logged in users ID matches the current discs user_id (i.e if this user owns this disc)
    if ($cur_topic['user_id']==$pun_user['id']) // check if one is owned by the user
      $array['owned'] = true;
  }
  foreach ($array as $cur_topic) {
    if ($cur_topic['owned']) { 
      $read = '<br /><input type="checkbox" disabled="disabled" checked="checked" /> <span style="color:#999">I own this!</span>';
    } else {
      $read = '<br /><input type="checkbox" name="discs[]" value="'.$cur_topic['id'].'" /> I own this!';
    }
  }
}
0 голосов
/ 01 марта 2010

Это предположение, поскольку я не знаю вашу схему, но я не вижу, чтобы вы указывали идентификатор пользователя в предложении WHERE.

Что насчёт чего-то вроде следующего?

  SELECT t.id, t.poster, t.subject, t.posted, t.last_post, t.last_post_id,
         t.last_poster, t.num_views, t.num_replies, t.closed, t.sticky,
         t.moved_to, t.topicimage, c.user_id, c.disc_id
    FROM topics AS t LEFT JOIN collections AS c ON c.disc_id = t.id
   WHERE forum_id = '.$id.'
     AND c.user_id = '.$user_id.'
ORDER BY t.sticky DESC;

Кроме того, вы присоединяетесь к идентификатору темы = идентификатору диска. Это намеренно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...