简体   繁体   English

SQL计算计数大于列值

[英]Sql calculate count greater than column value

I have table in which deleieverddate are saved, some of the delivered date are null and some of them are not I want to calculate the count for which delievered date is null and skip the delieverd date of those who are missed in between. 我有一个保存了deleieverddate的表,一些交货日期为null,有些则不是。我想计算延迟日期为null的计数,并跳过两者之间错过的延迟日期。

ie

deleievered date

NULL
NULL
NULL

count should be 3. 计数应为3。

ie

NULL
NULL
9/22/2017
NULL
10/22/2017
NULL

Count should be 1 here skip all previous where deievered date is not null 计数应为1,此处跳过指定日期不为空的所有先前记录

I have tried this but it is too costly. 我已经尝试过了,但这太昂贵了。

DECLARE @myTable TABLE
    (
      MessageId BIGINT ,
      ReceiverID VARCHAR(100)
    )

DECLARE @mySecondTable TABLE
    (
      MessageId BIGINT ,
      ReceiverID VARCHAR(100),
      DeliveredDate DATETIME
    )


DECLARE @myLastTable TABLE
    (
      MessageId BIGINT ,
      ReceiverID VARCHAR(100)
    )





INSERT  INTO @myTable
        ( MessageId ,
          ReceiverID

        )
        SELECT  MAX(MessageID) ,
                ReceiverID
        FROM    dbo.CM_MessageStatus
        WHERE   ReceiverID IN ( SELECT  *
                                FROM    string_split(@UserID, ',') )
                AND DeliveredDate IS NOT NULL
        GROUP BY ReceiverID






INSERT  INTO @mySecondTable
        ( MessageId ,
          ReceiverID,
          DeliveredDate

        )

SELECT  CM_MessageStatus.MessageID,
        dbo.CM_MessageStatus.ReceiverID,
        DeliveredDate
FROM    dbo.CM_MessageStatus
WHERE   DeliveredDate IS NULL AND

         ReceiverID IN ( SELECT  *
                            FROM    string_split(@UserID, ',') )
--GROUP BY dbo.CM_MessageStatus.ReceiverID,DeliveredDate




--Now check each userid
declare @ReceiverID NVARCHAR(MAX)
while exists (select * from @mySecondTable)
BEGIN

            select top 1 @ReceiverID = ReceiverID
            from @mySecondTable
            order by ReceiverID ASC 





        IF EXISTS( SELECT * FROM @myTable WHERE ReceiverID=@ReceiverID)
        BEGIN
                            INSERT  INTO @myLastTable
                                    ( MessageId ,
                                      ReceiverID

                                    )


                                    SELECT  MessageID,
                                            @ReceiverID
                                    FROM    @mySecondTable
                                    WHERE   DeliveredDate IS NULL
                                            AND MessageId > ( SELECT
                                                      MessageId
                                                      FROM
                                                      @myTable
                                                      WHERE
                                                      ReceiverID = @ReceiverID
                                                      )
                                                      AND ReceiverID=@ReceiverID
                                                      --GROUP BY ReceiverID
        END


        ELSE
        BEGIN
                INSERT  INTO @myLastTable
                                    ( MessageId ,
                                      ReceiverID

                                    )
                                   SELECT  MessageID ,
                                            ReceiverID
                                    FROM    @mySecondTable
                                    WHERE   DeliveredDate IS NULL
                                    AND ReceiverID=@ReceiverID
        END   


        delete @mySecondTable
        where ReceiverID = @ReceiverID
END 

    SELECT COUNT(MessageId) AS MessageId,ReceiverID FROM @myLastTable
    GROUP BY ReceiverID

It took 35 seconds for 8 hundred thousand which is too costly, how can I do this in one select. 花了35秒花了80万,这实在太昂贵了,我该如何选择呢? Efforts are share in the question. 问题中有共同的努力。

Well, you have to have some order to the data. 好吧,您必须对数据进行一些排序。 That is, an ID column, or something that represents when a row was inserted compared to all other rows. 也就是说,一个ID列,或代表什么时候插入一行与所有其他行相比的东西。 In this example, I use MessageID. 在此示例中,我使用MessageID。 Each time a row is inserted, it gets a new MessageID which is 1 greater than the previous. 每次插入一行时,它都会获得一个新的MessageID,该ID比上一行大1。 Without SOME column (insert date) or a PrimaryKey / Auto Increment column this is impossible. 没有SOME列(插入日期)或PrimaryKey / Auto Increment列,这是不可能的。 So, if you have one, here is how you can do it. 因此,如果您有一个,请按以下步骤进行。

declare @table table (MessageId  int identity(1,1), dt date)
insert into @table

values
(NULL),
(NULL),
('9/22/2017'),
(NULL),
('10/22/2017'),
(NULL)



select
    count(*)
from 
    @table
where 
    --limits rows to the last one where data is not null
    MessageID > (
    select max(MessageID)
    from @table
    where dt is not null)
or
    --if all dates are null
    (
    select max(dt)
    from @table) is null

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM