SQL SELECT顶行和聚合计数

时间:2013-12-22 10:59:49

标签: sql sql-server sql-server-2008 tsql

我无法绕过这个。我有一个客户 - 员工沟通系统。在管理员方面,我正在尝试检索用户列表,其中包含消息总数,新消息总数,最后消息日期,该用户的最后消息。

有点逻辑:

  • 发件人或收件人的值为0,表示员工发送或接收它。
  • X的发件人或收件人值,表示收到或发送了ID值为X的用户。

示例数据:

ID  |date                   |new    |sender |receiver   |message
----+-----------------------+-------+-------+-----------+------------
1   |2013-12-22 08:19:12    |1      |2      |0          |Hello
2   |2013-12-22 08:23:19    |0      |0      |2          |Hello There
3   |2013-12-22 08:23:19    |0      |0      |4          |Hello There
4   |2013-12-22 10:09:44    |1      |2      |0          |The latest message

期望的输出:

user ID |total_messages |total_new  |latest_date            |latest_messsage
------------------------------------------------------------------------------
2       |3              |2          |2013-12-22 10:09:44    |The latest message
4       |1              |0          |2013-12-22 08:23:19    |Hello There

我正在使用SQL Server 2008

3 个答案:

答案 0 :(得分:1)

拆分选择第一行和两个查询中的聚合行的逻辑,并将结果UNION。

SELECT TOP 1 --columns-- 
FROM yourTable

UNION ALL

SELECT --columns-- 
FROM yourTable
GROUP BY --columns--

(没有关于表格结构的更多细节或所需的输出,这是我能提出的最佳答案)

答案 1 :(得分:1)

我不知道你的数据库表是什么。但我可以告诉你有一个消息表和一个用户表。

SELECT 
    [userId], 
    (SELECT 
         count(*)
     FROM messages
     WHERE u.userId = messages.UserId) AS totalMessages, 
    (SELECT
         TOP 1 [TimeStamp]
     FROM messages
     WHERE messages.UserId = u.UserId
     ORDER BY messages.MessageId DESC), 
    (SELECT
         TOP 1 [Message]
     FROM messages
     WHERE messages.UserId = u.UserId
     ORDER BY messages.MessageId DESC)
FROM users u

您可以像这样计算发件人和收件人列。

答案 2 :(得分:1)

由于用户是否为您的总计发送或接收似乎无关紧要,因此您可以通过一个列(我使用CTE)将用户(发件人或收件人)列出的消息数据列为一种方式,然后使用该集合进行聚合,并将JOIN自身用于获取latest_message

WITH Users_CTE AS
(
  SELECT sender AS user_id, ID, new, date, message
  FROM Messages
  WHERE sender <> 0
  UNION
  SELECT receiver AS user_id, ID, new, date, message
  FROM Messages
  WHERE receiver <> 0
)

SELECT m.user_id, m.total_messages, m.total_new, m.latest_date, u.message AS latest_message
FROM (SELECT user_id
        , COUNT(*) AS total_messages
        , SUM(new) AS total_new
        , MAX(date) AS latest_date
      FROM Users_CTE
      GROUP BY user_id) AS m
  INNER JOIN Users_CTE AS u ON u.user_id = m.user_id
    AND u.date = m.latest_date

sqlfiddle