SQL Server Row_number() 与 GROUP BY 一起使用

发布于 2024-12-11 02:05:47 字数 2585 浏览 2 评论 0原文

我有“GetConversationPaged”sp,它从名为“user_messages_index”的表中选择分页数据,并在名为“social_user_messages”的表中的对话中包含“lastmesage”。 我不确定它是否可以进行微调,但它可以在缺少一件事的情况下工作。我想按我通过 select MAX(messageId) 获得的lastMessageId 对“Row_number”进行排序。

PS:我有消息索引和消息表,因为我希望人们向多个收件人发送相同的消息。我使用索引表而不是一遍又一遍地插入相同的消息

那么,我如何按最新消息ID对结果进行排序?


这是我正在使用的表和sps

--index table--

CREATE TABLE [dbo].[social_user_messages_index](
[senderId] [int] NOT NULL,
[recipientId] [int] NOT NULL,
[messageId] [int] NOT NULL,
[isRead] [bit] NOT NULL
 ) ON [PRIMARY]

--messages table --

CREATE TABLE [dbo].[social_user_messages](
[id] [int] IDENTITY(1,1) NOT NULL,
[message] [nvarchar](1000) NOT NULL,
[sendDate] [datetime] NOT NULL,
) ON [PRIMARY]

--sp--

ALTER PROCEDURE [dbo].[GetConversationPaged]
@userId int,
@isRead bit,
@PageNumber int,
@PageSize int
AS
BEGIN

    DECLARE @FirstRow  INT, @LastRow   INT, @RowCount  INT, @PageCount INT 
    --- find recordcount and pages 
    SELECT @RowCount = COUNT(1) OVER(), 
           @PageCount = COUNT(*) OVER() / @PageSize 
            FROM   social_user_mesages_index s
            WHERE  s.recipientId = @userId and s.isRead=@isRead
            GROUP BY senderId 
    --- calculate pages
    IF @RowCount % @PageSize != 0 SET @PageCount = @PageCount + 1 
    IF @PageNumber < 1  SET @PageNumber = 1 
    IF @PageNumber > @PageCount  SET @PageNumber = @PageCount 
    --- select paging data
    SELECT currentpage = @PageNumber, totalpages = @PageCount, totalrows = @RowCount 
    SET @FirstRow = ( @PageNumber - 1 ) * @PageSize + 1;
    SET @LastRow = ( @PageNumber - 1 ) * @PageSize + @PageSize; 

    --- select records     
    WITH mytable 
         AS (

            SELECT  Row_number() OVER (ORDER BY (SELECT 1)) AS rownumber,
                    (Select name from domains_users d where d.id=s.senderId) as senderName,
                    (select MAX(messageId)) as lastMessageId,
                    (select m.[message] from social_user_messages m where m.id = (select MAX(messageId))) as [message]
                    --,(select m.sendDate from social_user_messages m where m.id = (select MAX(messageId))) as lastMessageDate
                    ,senderId   
            FROM   social_user_mesages_index s
            WHERE  s.recipientId = @userId and s.isRead=@isRead
            GROUP BY senderId 

         ) 

    SELECT * 
    FROM   mytable 
    WHERE  rownumber BETWEEN @FirstRow AND @LastRow 
    ORDER  BY rownumber ASC; 
END

I have "GetConversationPaged" sp that selects paged data from table called "user_messages_index" and includes "lastmesage" in conversation from table called "social_user_messages".
I'm not sure if it can be fine tuned but it works with one thing missing. I want to sort "Row_number" by lastMessageId which i get with select MAX(messageId).

PS: I have message index and messages tables because i wanted people to send same message to multiple recipients. Instead of inserting same message over and over i use index table

So, how can I sort results by latest message id?


Here are table and sps i'm using

--index table--

CREATE TABLE [dbo].[social_user_messages_index](
[senderId] [int] NOT NULL,
[recipientId] [int] NOT NULL,
[messageId] [int] NOT NULL,
[isRead] [bit] NOT NULL
 ) ON [PRIMARY]

--messages table--

CREATE TABLE [dbo].[social_user_messages](
[id] [int] IDENTITY(1,1) NOT NULL,
[message] [nvarchar](1000) NOT NULL,
[sendDate] [datetime] NOT NULL,
) ON [PRIMARY]

--sp--

ALTER PROCEDURE [dbo].[GetConversationPaged]
@userId int,
@isRead bit,
@PageNumber int,
@PageSize int
AS
BEGIN

    DECLARE @FirstRow  INT, @LastRow   INT, @RowCount  INT, @PageCount INT 
    --- find recordcount and pages 
    SELECT @RowCount = COUNT(1) OVER(), 
           @PageCount = COUNT(*) OVER() / @PageSize 
            FROM   social_user_mesages_index s
            WHERE  s.recipientId = @userId and s.isRead=@isRead
            GROUP BY senderId 
    --- calculate pages
    IF @RowCount % @PageSize != 0 SET @PageCount = @PageCount + 1 
    IF @PageNumber < 1  SET @PageNumber = 1 
    IF @PageNumber > @PageCount  SET @PageNumber = @PageCount 
    --- select paging data
    SELECT currentpage = @PageNumber, totalpages = @PageCount, totalrows = @RowCount 
    SET @FirstRow = ( @PageNumber - 1 ) * @PageSize + 1;
    SET @LastRow = ( @PageNumber - 1 ) * @PageSize + @PageSize; 

    --- select records     
    WITH mytable 
         AS (

            SELECT  Row_number() OVER (ORDER BY (SELECT 1)) AS rownumber,
                    (Select name from domains_users d where d.id=s.senderId) as senderName,
                    (select MAX(messageId)) as lastMessageId,
                    (select m.[message] from social_user_messages m where m.id = (select MAX(messageId))) as [message]
                    --,(select m.sendDate from social_user_messages m where m.id = (select MAX(messageId))) as lastMessageDate
                    ,senderId   
            FROM   social_user_mesages_index s
            WHERE  s.recipientId = @userId and s.isRead=@isRead
            GROUP BY senderId 

         ) 

    SELECT * 
    FROM   mytable 
    WHERE  rownumber BETWEEN @FirstRow AND @LastRow 
    ORDER  BY rownumber ASC; 
END

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

懵少女 2024-12-18 02:05:47

在您的 CTE 中,social_user_messages_index 拼写错误。我还删除了您在几个地方的Group BY SenderId,并更新了 CTE。如果这没有达到您的期望,请告诉我,我可以调整它:

ALTER PROCEDURE [dbo].[GetConversationPaged]
@userId int,
@isRead bit,
@PageNumber int,
@PageSize int
AS
BEGIN

   DECLARE @FirstRow  INT, @LastRow   INT, @RowCount  INT, @PageCount INT 
   --- find recordcount and pages 
   SELECT @RowCount = COUNT(1) OVER()
      , @PageCount = COUNT(*) OVER() / @PageSize 
   FROM   dbo.social_user_messages_index AS s
   WHERE  s.recipientId = @userId and s.isRead=@isRead

   --- calculate pages
   IF @RowCount % @PageSize != 0 SET @PageCount = @PageCount + 1 
   IF @PageNumber < 1 SET @PageNumber = 1 
   IF @PageNumber > @PageCount SET @PageNumber = @PageCount 

   --- select paging data
   SELECT currentpage = @PageNumber
      , totalpages = @PageCount
      , totalrows = @RowCount;
   SET @FirstRow = ( @PageNumber - 1 ) * @PageSize + 1;
   SET @LastRow = ( @PageNumber - 1 ) * @PageSize + @PageSize; 

   --- select records     
   WITH mytable AS
   (
      SELECT Row_number() OVER (ORDER BY MessageId DESC) AS rownumber
         , du.name as senderName
         , m.Message
         , senderId
      FROM social_user_messages_index AS s
      INNER JOIN dbo.domains_users AS du ON s.SenderId = du.id
      INNER JOIN dbo.social_user_messages AS m ON s.messageId = m.id
      WHERE s.recipientId = @userId
         AND s.isRead=@isRead
   )
   SELECT * 
   FROM   mytable 
   WHERE  rownumber BETWEEN @FirstRow AND @LastRow 
   ORDER  BY rownumber ASC;
END

In your CTE, you had social_user_messages_index misspelled. I also removed the Group BY SenderId you had a few places, and updated the CTE. If this doesn't do what you were hoping, let me know and I can tweak it:

ALTER PROCEDURE [dbo].[GetConversationPaged]
@userId int,
@isRead bit,
@PageNumber int,
@PageSize int
AS
BEGIN

   DECLARE @FirstRow  INT, @LastRow   INT, @RowCount  INT, @PageCount INT 
   --- find recordcount and pages 
   SELECT @RowCount = COUNT(1) OVER()
      , @PageCount = COUNT(*) OVER() / @PageSize 
   FROM   dbo.social_user_messages_index AS s
   WHERE  s.recipientId = @userId and s.isRead=@isRead

   --- calculate pages
   IF @RowCount % @PageSize != 0 SET @PageCount = @PageCount + 1 
   IF @PageNumber < 1 SET @PageNumber = 1 
   IF @PageNumber > @PageCount SET @PageNumber = @PageCount 

   --- select paging data
   SELECT currentpage = @PageNumber
      , totalpages = @PageCount
      , totalrows = @RowCount;
   SET @FirstRow = ( @PageNumber - 1 ) * @PageSize + 1;
   SET @LastRow = ( @PageNumber - 1 ) * @PageSize + @PageSize; 

   --- select records     
   WITH mytable AS
   (
      SELECT Row_number() OVER (ORDER BY MessageId DESC) AS rownumber
         , du.name as senderName
         , m.Message
         , senderId
      FROM social_user_messages_index AS s
      INNER JOIN dbo.domains_users AS du ON s.SenderId = du.id
      INNER JOIN dbo.social_user_messages AS m ON s.messageId = m.id
      WHERE s.recipientId = @userId
         AND s.isRead=@isRead
   )
   SELECT * 
   FROM   mytable 
   WHERE  rownumber BETWEEN @FirstRow AND @LastRow 
   ORDER  BY rownumber ASC;
END
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文