我正在使用3个表格: 用户(ID,名字,姓氏,类型,禁用) 评论(ID,发件人,日期) comment_recipient(COMMENT_ID,USER_ID)
我试图找到给定或收到某个月/年评论的用户的数据。我想要的结果行: 名字|姓氏|评论给出了|收到的评论|月|年
单个评论可以有多个收件人(comment_recipient中有许多条目)
我开始关注这个问题,看起来有点类似: PubNub Access Manager to lock down access to your channels
以下是我目前的情况:
SELECT
firstName AS 'First Name',
lastName AS 'Last Name',
given AS 'Comments Given',
received AS 'Comments Received',
MONTHNAME(d_yearmonth) AS Month,
YEAR(d_yearmonth) AS Year
FROM (
SELECT
LAST_DAY(c.date) AS d_yearmonth,
u.firstName,
u.lastName,
(SELECT COUNT(*) FROM comment AS c1 WHERE c1.sender=c.sender
AND LAST_DAY(c1.date)=d_yearmonth) AS given,
'24' AS received
FROM comment AS c
JOIN comment_recipient AS cr ON cr.comment_id=c.id
JOIN user AS u ON u.id=c.sender
WHERE u.type<4 AND u.disabled=0
GROUP BY
d_yearmonth
) AS s
ORDER BY Year DESC,
MONTH(d_yearmonth) DESC
我只是在使用&#39; 24&#39;为了收到&#39;目前,我正试图一次解决这个问题
我不需要计算每个用户或每个月,所以如果给定和收到它们都会返回0,则可以忽略它们
答案 0 :(得分:1)
如果你把它分成两部分,我认为这个问题会更容易解决。
您可以使用联合“合并”发送和接收的消息。
完整查询可能如下所示:
SELECT user_id,
lastName,
firstName,
SUM(sent) as sent,
SUM(received) as received,
year,
month
FROM (
SELECT
c.sender as user_id,
u.lastname as lastName,
u.firstname as firstName,
count(*) as sent,
0 as received,
YEAR(date) as year,
MONTH(date) as month
FROM Comment as C
JOIN user AS u ON u.id=c.sender
WHERE u.type<4 AND u.disabled=0
GROUP by user_id, year, month
UNION ALL
select cr.user_id as user_id,
u.lastname as lastName,
u.firstname as firstName,
0 as sent,
count(*) as received,
YEAR(date) as year,
MONTH(date) as month
FROM comment_recipient cr
JOIN comment c ON c.id = cr.comment_id
JOIN user u on u.id = cr.user_id
WHERE u.type<4 AND u.disabled=0
GROUP by user_id, year, month
) A
GROUP by user_id, year, month;
答案 1 :(得分:0)
您将从表中生成三个汇总数据集。他们是
然后你可以一起加入他们
您需要为每个子查询提供子查询。从月末日期开始。
SELECT DISTINCT LAST_DAY(`date`) month_end
FROM comment
您需要发送的评论,按用户ID和月份汇总
SELECT COUNT(*) sent,
sender id,
LAST_DAY(`date`) month_end
FROM comment
GROUP BY sender, LAST_DAY(`date`)
您需要收到的评论,按用户ID和月份汇总。这需要加入评论表,以获取评论的日期。
SELECT COUNT(*) received,
cr.user_id id,
LAST_DAY(c.`date`) month_end
FROM comment_recipient cr
JOIN comment c ON cr.comment_id = c.id
GROUP BY cr.user_id, LAST_DAY(c.`date`)
然后,您需要使用用户表将这三个子查询(将它们视为虚拟表)加入。
SELECT u.firstName, u.lastName,
ISNULL(s.sent,0) sent,
ISNULL(r.received,0) received,
MONTHNAME(d.month_end), YEAR(d.month_end)
FROM (
SELECT DISTINCT LAST_DAY(`date`) month_end
FROM comment
) AS d
JOIN user u ON 1=1
LEFT JOIN (
SELECT COUNT(*) sent,
sender id,
LAST_DAY(`date`) month_end
FROM comment
GROUP BY sender, LAST_DAY(`date`)
) s ON d.month_end=s.month_end AND u.id = s.id
LEFT JOIN (
SELECT COUNT(*) received,
cr.user_id id,
LAST_DAY(c.`date`) month_end
FROM comment_recipient cr
JOIN comment c ON cr.comment_id = c.id
GROUP BY cr.user_id, LAST_DAY(c.`date`)
) r ON d.month_end=r.month_end AND u.id = r.id
WHERE u.type < 4 AND u.disabled = 0
AND NOT (r.received IS NULL AND s.sent IS NULL)
AND d.month_end > CURDATE() - INTERVAL 1 YEAR
获取所需的所有行有点棘手。这就是我们进行ISNULL和LEFT JOIN操作的原因。我们还必须在单独的查询中进行聚合。如果我们只是加入评论和收件人,我们最终会有很多重复。