![](/img/trans.png)
[英]Need help pulling into multiple columns from one database table - mysql_query
[英]Need help with a multiple table query in mysql
我正在與kohana建立論壇。 我知道那里已經有不錯的,免費的論壇軟件,但這是針對家庭網站的,所以我想我會將其用作學習體驗。 我也沒有使用Kohana內置的ORM,因為我想在構建論壇的過程中進一步了解SQL。
對於我的論壇,我有4個主要表格:
USERS
TOPICS
POSTS
COMMENTS
主題表:ID(自動遞增),主題行。
USERS表:用戶名,電子郵件,姓氏和其他一些不相關的行
POSTS表:id(自動遞增),post-title,post-body,topic-id,user-id,post-date,updated-date,updated-by(其中將包含創建該人員的用戶ID)最近的評論)
注釋表:id(自動遞增),post-id,user-id和注釋
我希望在論壇主頁面上:
這是我到目前為止的查詢:
SELECT topics.id AS topic-id,
topics.topic,
post-user.id AS user-id,
CONCAT_WS(' ', post-user.first-name, post-user.last-name) AS name,
recent-post.id AS post-id,
post-num.post-total,
recent-post.title AS post-title,
recent-post.update_date AS updated-date,
recent-post.updated-by AS updated-by
FROM topics
JOIN (SELECT posts.topic-id,
COUNT(*) AS post-total
FROM POSTS
WHERE posts.topic-id = topic-id
GROUP BY posts.topic-id) AS post-num ON topics.id = post-num.topic-id
JOIN (SELECT posts.*
FROM posts
ORDER BY posts.update-date DESC) AS recent-post ON topics.id = recent-post.topic-id
JOIN (SELECT users.*,
posts.user-id
FROM users, posts
WHERE posts.user-id = users.id) as post-user ON recent-post.user_id = post-user.id
GROUP BY topics.id
該查詢幾乎可以正常工作,因為它將獲取有關具有帖子主題的所有信息。 但是它不會返回沒有任何帖子的主題 。
我確定查詢效率低下並且是錯誤的,因為它對posts表進行了兩個子選擇,但這是我所要指出的唯一方法。
ORDER BY
沒有任何意義。 topic_id
, user_id
等(而不是每個表中的“ id
”),並且您不必在選擇列表中使用別名。 首先獲取每個主題的最新帖子,以及相關的用戶信息:
SELECT t.topic_id, t.topic,
u.user_id, CONCAT_WS(' ', u.first_name, u.last_name) AS full_name,
p.post_id, p.title, p.update_date, p.updated_by
FROM topics t
INNER JOIN
(posts p INNER JOIN users u ON (p.updated_by = u.user_id))
ON (t.topic_id = p.topic_id)
LEFT OUTER JOIN posts p2
ON (p.topic_id = p2.topic_id AND p.update_date < p2.update_date)
WHERE p2.post_id IS NULL;
然后在一個單獨的,更簡單的查詢中獲取每個主題的帖子數。
SELECT t.topic_id, COUNT(*) AS post_total
FROM topics t LEFT OUTER JOIN posts p USING (topic_id)
GROUP BY t.topic_id;
合並您的應用程序中的兩個數據集。
為了確保獲得沒有帖子的主題的結果,您將需要使用LEFT JOIN而不是JOIN進行主題和下一張表之間的第一次連接。 LEFT JOIN的意思是“即使與右表不匹配,也總是為左表中的每一行返回結果集行。”
現在要走了,但是稍后我將嘗試研究效率問題。
我將在子查詢中使用left join
聯接來拉回正確的主題,然后您可以在此之外做一些其他工作以獲取一些用戶信息。
select
s.topic_id,
s.topic,
u.user_id as last_updated_by_id,
u.user_name as last_updated_by,
s.last_post,
s.post_count
from
(
select
t.id as topic_id,
t.topic,
t.user_id as orig_poster,
max(coalesce(p.post_date, t.post_date)) as last_post,
count(*) as post_count --would be p.post_id if you don't want to count the topic
from
topics t
left join posts p on
t.id = p.topic_id
group by
t.topic_id,
t.topic,
t.user_id
) s
left join posts p on
s.topic_id = p.topic_id
and s.last_post = p.post_date
and s.post_count > 1 --0 if you're using p.post_id up top
inner join users u on
u.id = coalesce(p.user_id, s.orig_poster)
order by
s.last_post desc
該查詢確實引入了coalesce
和left join
,這是值得研究的非常好的概念。 對於兩個參數(如此處使用的參數),您也可以在MySQL中使用ifnull
,因為它在功能上是等效的。
請記住,這是MySQL專有的(如果您需要移植此代碼)。 其它數據庫有那個(其他功能isnull
在SQL Server中, nvl
在Oracle中,等等,等等)。 我使用了coalesce
以便可以保留所有ANSI標准的查詢。
這是一個非常復雜的查詢。 您應該注意,JOIN語句會將您的主題限制為那些發表文章的主題。 如果主題沒有帖子,則JOIN語句將其過濾掉。
請嘗試以下查詢。
SELECT *
FROM
(
SELECT T.Topic,
COUNT(AllTopicPosts.ID) NumberOfPosts,
MAX(IFNULL(MostRecentPost.Post-Title, '') MostRecentPostTitle,
MAX(IFNULL(MostRecentPostUser.UserName, '') MostRecentPostUser
MAX(IFNULL(MostRecentPost.Updated_Date, '') MostRecentPostDate
FROM TOPICS
LEFT JOIN POSTS AllTopicPosts ON AllTopicPosts.Topic_Id = TOPICS.ID
LEFT JOIN
(
SELECT *
FROM Posts P
WHERE P.Topic_id = TOPICS.id
ORDER BY P.Updated_Date DESC
LIMIT 1
) MostRecentPost ON MostRecentPost.Topic_Id = TOPICS.ID
LEFT JOIN USERS MostRecentPostUser ON MostRecentPostUser.ID = MostRecentPost.User_Id
GROUP BY T.Topic
)
ORDER BY MostRecentPostDate DESC
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.