MySQL дубликат выбрать и вычесть 1 из дубликатов - PullRequest
1 голос
/ 17 февраля 2012

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

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

Теперь вопрос.

I have a table for news.

id   |  news_username    (who post news)


news_text Table

news_id  |  username  |  news_text   

(Here user: can be editor of the news or a person who  posted news)

User Table

username |  title 

В этой таблице есть новость 'id' и новость 'username'. Имя пользователя - это имя пользователя, публикующего новости. в таблице также есть еще несколько полей, но они не важны.

Тогда есть таблица news_text и внутри нее помещается текст для новости. В этой таблице есть поля «news_id» и «username». На этот раз имя пользователя - это поле лица, опубликовавшего новость ИЛИ имя пользователя, отредактировавшего сообщение.

Тогда у меня есть пользовательская таблица с полем 'username' и полем 'title' с заголовком для пользователя. В этом

Надеюсь, ты еще со мной.

Короче говоря, если пользователь публикует новостную статью, текст будет находиться внутри таблицы «news_text», и когда редактор редактирует пост, измененный текст будет вставлен как новый текст для той же статьи. Это сделано для того, чтобы оригинальный постер увидел, что было изменено в его сообщении.

теперь приходит мой вызов. Мне нужно выяснить, как я могу получить количество правок, которые сделал редактор. НО потому, что сам редактор может публиковать новости, это означает, что мне нужно искать все новости, где имя пользователя не равно исходному постеру и где он ищет дубликаты в таблице news_text, чтобы увидеть, как редактор отредактировал свой собственный пост.

Я действительно надеюсь, что люди немного понимают, что мне нужно делать. надеюсь, ты сможешь мне помочь.


в комментарии Маркус Адамс указал мне, как на сайте использовалось последнее изменение.

Это поле через поле даты / времени. Когда редактирование размещено, оно будет вставлено в поле news_text, и для нового редактирования будет указана дата / время. И с этим это определит текст ведьмы, чтобы захватить для новости.

надеюсь, это понятно

Ответы [ 3 ]

1 голос
/ 17 февраля 2012

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

SELECT
    user.*,
    COUNT(*) AS edits

FROM user

// Join posts that aren't this users
INNER JOIN news
ON news.username != user.username

// Join edits for the above posts that are this users
INNER JOIN news_text
ON news_text.news_id = news.id
AND news_text.username != user.username

И с заполнителем, если вы хотите выбрать конкретную новостную статью

SELECT
    user.*,
    COUNT(*) AS edits

FROM user

// Join posts that aren't this users
INNER JOIN news
ON news.username != user.username
AND news.id = [[SPECIFIC ID]]

// Join edits for the above posts that are this users
INNER JOIN news_text
ON news_text.news_id = news.id
AND news_text.username != user.username

Или, может быть, если вы хотите увидеть, сколько изменений внес конкретный пользователь в конкретную статью

SELECT
    user.*,
    COUNT(*) AS edits

FROM user

// Join posts that aren't this users
INNER JOIN news
ON news.username != user.username
AND news.id = [[SPECIFIC ID]]

// Join edits for the above posts that are this users
INNER JOIN news_text
ON news_text.news_id = news.id
AND news_text.username != user.username

WHERE user.username = [[SPECIFIC USERNAME]]

РЕДАКТИРОВАТЬ Альтернативный подход, если вы хотите подсчитать все сообщения, сделанные пользователем, которые НЕ являются оригинальными сообщениями, т.е. все изменения, даже если они редактируют свое собственное сообщение

SELECT
    user.*,
    news.*,
    COUNT(*)-IF(news.username=user.username,1,0) AS edits
FROM user

// This join will give us all posts made by user
INNER JOIN news_text
ON news_text.username = user.username

// Also join the news id
INNER JOIN news
ON news_text.news_id = news.id

GROUP BY user.username, news.id

Это вернет 1 строку на пользователя для каждого news.id, подсчитав количество правок, выполненных пользователем, поэтому, чтобы взять это и вернуть итоги, вы могли бы вместо этого сделать это, чтобы возвратить количество правок, выполненных одним пользователем имя

SELECT
    username,
    sUM(edits)
FROM (
    SELECT
        news_text.username.username,
        COUNT(*)-IF(news.username=news_text.username,1,0) AS edits
    FROM news_text
    ON news_text.username = [[USER TO CHECK]]

    // Also join the news id
    INNER JOIN news
    ON news_text.news_id = news.id

    GROUP BY news.id
)
0 голосов
/ 17 февраля 2012

Насколько я понимаю, у вас есть повторяющиеся строки news_text для определенного элемента новостей (news_id). Кроме того, у вас есть поле edit_date в таблице news_text, и вы получаете news_text с последней датой edit_date, чтобы получить последнюю версию новости.

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

Вот одно из решений. Это для конкретного пользователя:

SELECT COUNT(*) AS edits
FROM user u
JOIN news n
  ON n.username <> u.username
JOIN news_text nt1
  ON nt1.news_id = n.news_id
  AND nt1.username = u.username
JOIN news_text nt2
  ON nt2.news_id = n.news_id
  AND nt2.edit_date < nt1.edit_date
  AND nt2.username <> u.username
LEFT JOIN news_text nt3
  ON nt3.news_id = n.news_id
  AND nt3.edit_date > nt2.edit_date AND nt3.edit_date < nt1.edit_date
WHERE u.username = 'myuser'
  AND nt3.news_id IS NULL
  • Сначала собираются все новости, которые не были созданы пользователем (ON n.username <> u.username)
  • Затем он собирает все news_texts для каждого из тех новостей, которые отредактировал наш пользователь (ON nt1.news_id = n.news_id AND nt1.username = u.username)
  • Затем он собирает все предыдущие версии для вышеупомянутых, которые были от других пользователей (ON nt2.news_id = n.news_id AND nt2.edit_date < nt1.edit_date AND nt2.username <> u.username)
  • Затем он собирает любые версии между текущей и предыдущей, для исключения позже (ON nt3.news_id = n.news_id AND nt3.edit_date > nt2.edit_date AND nt3.edit_date < nt1.edit_date)
  • Затем фильтры для нашего пользователя (WHERE u.username = 'myuser')
  • Затем он отфильтровывает правки, которые были между текущим и предыдущим, гарантируя, что у нас будет только предыдущая версия (nt3.news_id IS NULL)
0 голосов
/ 17 февраля 2012

Я бы предположил, что самый простой способ сделать это - два запроса:

Один, чтобы найти общее количество изменений, внесенных пользователем

например. SELECT COUNT(*) FROM news_text WHERE username = {USERNAME} GROUP BY username

И затем один, чтобы найти общее количество сообщений, созданных этим пользователем

например. SELECT COUNT(*) FROM news WHERE username = {USERNAME} GROUP BY username

И вычтите одно из другого.

Или делайте запросы для всех пользователей и просто отбирайте тех, которые вам нужны. (Или объедините их в один запрос, если вы действительно хотите).

...