MySQL: упорядочение по двум счетам из другой таблицы? - PullRequest
3 голосов
/ 13 августа 2011

У меня есть одна таблица sql, которая выглядит так: "posts":

id | user
--------------------------------
0  | tim
1  | tim
2  | bob

И еще один, называемый «голоса», который хранит либо положительные, либо отрицательные голоса на сообщения в таблице «сообщения»:

id | postID | type
--------------------------------
0  | 0      | 0
1  | 2      | 1
2  | 0      | 1
3  | 0      | 1
4  | 3      | 0

В этой таблице 'type' это либо 0 для downvote, либо 1 для upvote.

Как бы я упорядочил посты по "тим" по количеству (upvotes - downvotes) поста?

Ответы [ 3 ]

3 голосов
/ 13 августа 2011
SELECT
  p.id,
  p.user,
  SUM(v.type * 2 - 1) AS votecount
FROM posts p
  LEFT JOIN votes v ON p.id = v.postID
WHERE p.user = 'tim'
GROUP BY p.id, p.user
ORDER BY votes DESC

ОБНОВЛЕНИЕ - p и v объяснено.

В этом запросе p и v представляют собой псевдонимы соответственно posts и votes. Псевдоним, по сути, является альтернативным именем и определяется только в рамках оператора, который его объявляет (в данном случае, оператора SELECT). Псевдоним может иметь не только таблица, но и столбец. В этом запросе votecount является псевдонимом столбца, представленного выражением SUM(v.type * 2 - 1). Но сейчас речь идет только о таблицах.

Прежде чем я продолжу объяснение псевдонимов таблиц, я кратко объясню, почему вам может понадобиться добавлять префиксы к именам столбцов, например, posts.id, а не id. По сути, когда запрос ссылается на более чем одну таблицу, как в этом случае, может оказаться полезным всегда добавлять префиксы имен столбцов к соответствующим именам таблиц. Таким образом, когда вы пересматриваете старый скрипт, вы всегда можете сказать, какой столбец принадлежит какой таблице, без необходимости искать структуры таблиц, на которые ссылаются. Кроме того, обязательно включать ссылку на таблицу, если ее опустить, что создает неопределенность в отношении того, к какой таблице принадлежит столбец. (В этом случае ссылка на столбец id без ссылки на таблицу posts создает неоднозначную ситуацию, поскольку каждая таблица имеет свою собственную id.)

Теперь большой и сложный запрос может быть трудным для чтения, когда вы пишете полные имена таблиц перед именами столбцов. Здесь (короткие) псевдонимы пригодятся: они облегчают чтение и понимание запроса, хотя я уже понял, что не все люди разделяют это мнение, и поэтому вы должны судить сами: этот вопрос содержит две версии одного и того же запроса, одна с ссылками на таблицы с длинными именами, а другая с ссылками на короткие псевдонимы, а также мнение (в комментарии к одному из ответов), почему псевдонимы не подходят.

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

Эта статья по документации MySQL содержит официальный синтаксис для таблиц псевдонимов в MySQL (который фактически такой же, как в стандартном SQL).

1 голос
/ 13 августа 2011

Редактировать: я вырезал подзапрос, так как в MySQL его не нужно.Исходный запрос был переносимым, но ненужным для mysql.

select
    p.id, SUM(case 
                when v.type = 0 then -1 
                when v.type = 1 then 1 
                else 0 end) as VoteCount 
from
    posts p
    left join votes v
        on  p.id = v.postid
where
    p.[user] = 'tim'
group by
    p.id
order by
    VoteCount desc
1 голос
/ 13 августа 2011

Не проверено, но должно работать:

select post.id, sum(if(type = 0, -1, 1)) as score
from posts join votes on post.id = votes.postID
where user = 'tim'
group by post.id
order by score

Планируете ли вы согласиться с СО? ; -)

...