简体   繁体   English

如何在SQL Server 2014中从同一表中获取比较记录?

[英]How to get comparing records from the same table in SQL Server 2014?

I have a table that shows the entry and exit of items into the warehouse. 我有一张桌子,显示物品进入和离开仓库的情况。 The Camera 1 and Camera 2 document the entry time and exit time respectively of that item. 摄像机1和摄像机2分别记录该项目的进入时间和退出时间。 The cameras then classify the item as it enters and leaves the checkpoint with the help of lasers. 然后,摄像机会在激光进入的情况下对进入和离开检查点的物品进行分类。 Eg: Big box: Class 5, Medium Box: Class 3, Small Box: Class 2. 例如:大盒子:5类,中盒子:3类,小盒子:2类。

Sometimes, the cameras classification doesn't match each other. 有时,相机分类彼此不匹配。 Eg: Classification at entry can be Medium box and on exit can be Small box. 例如:入口处的分类可以是中框,出口处的分类可以是小框。

I need to find the number of transactions where the class didn't match for the same TransactionDetail and then a percentage of those class mismatches against all the transaction for a certain time range. 我需要找到对于同一TransactionDetail类不匹配的TransactionDetail ,然后在特定时间范围内,针对所有事务找到这些类不匹配的百分比。

My table looks somewhat like this: 我的桌子看起来像这样:

---------------------------------------------------------------------------
| AVDetailID | TransDetailID | AVClassID | CamID | CreatedDate            |
---------------------------------------------------------------------------
| 20101522   | 54125478      | 5         | 1     | 2017-05-08 10:15:01:560|
| 20101523   | 54125478      | 5         | 2     | 2017-05-08 10:15:01:620|
| 20101524   | 54125479      | 3         | 1     | 2017-05-08 10:15:03:120|
| 20101525   | 54125479      | 2         | 2     | 2017-05-08 10:15:03:860|
| 20101526   | 54125480      | 4         | 1     | 2017-05-08 10:15:06:330|
| 20101527   | 54125480      | 4         | 2     | 2017-05-08 10:15:06:850|
---------------------------------------------------------------------------

So, in the above case the class changes from 3 to 2 in record 3 and 4. That is one transaction where the class changed. 因此,在上述情况下,类别在记录3和4中从3更改为2。这是类别更改的一个事务。 I need to get a percentage of all transactions that where the class changed between each cameras. 我需要获得所有摄像机在类之间更改的所有事务的百分比。

The code I've used so far is below. 我到目前为止使用的代码如下。 I just need to find a way to get a percentage of the total Transactions. 我只需要找到一种方法来获取总交易额的百分比。

DECLARE @MinDate DATE = '20170406',
        @MaxDate DATE = '20170407';

SELECT  COUNT(tdBefore.TransDetailId) TD
        --,SUM((COUNT(*) OVER() / allRecords.Count) * 100) AS DiffPercent

FROM    AVTransDetail AS tdBefore
INNER JOIN AVTransDetail AS tdAfter
    ON tdBefore.TransDetailID = tdAfter.TransDetailID 
    AND tdBefore.ACClassID = 1
    AND tdAfter.ACClassID = 2
CROSS APPLY
(
    SELECT COUNT(*) AS [Count]
    FROM AVTransDetail
    WHERE tdBefore.DateCreated >= @MinDate
        AND tdAfter.DateCreated <= @MaxDate
) AS allRecords
WHERE   tdBefore.AVCClassId <> tdAfter.AVCClassId 
        AND tdBefore.DateCreated >= @MinDate
        AND tdAfter.DateCreated <= @MaxDate

How do I create a column for percentage of total transactions? 如何为总交易量百分比创建列?

This worked with your sample data. 这可以处理您的样本数据。

DECLARE @MinDate DATETIME = '5/8/2017 12:00AM';
DECLARE @MaxDate DATETIME = '5/8/2017 11:59PM';

WITH cam1 AS ( 
    SELECT TransDetailID,AVClassID
    FROM AVTransDetail
    WHERE CreatedDate BETWEEN @MinDate AND @MaxDate
    AND
    CamID = 1),

cam2 AS (
    SELECT TransDetailID,AVClassID
    FROM AVTransDetail
    WHERE CreatedDate BETWEEN @MinDate AND @MaxDate
    AND
    CamID = 2)

SELECT COUNT(*)'Total',SUM(CASE WHEN c1.AVClassID = c2.AVClassID THEN 0 ELSE 1 END)'NonMatch',
       SUM(CASE WHEN c1.AVClassID = c2.AVClassID THEN 0 ELSE 1 END) * 100.00/COUNT(*)'Percentage'
FROM cam1 c1
     JOIN cam2 c2 ON c1.TransDetailID=c2.TransDetailID

Try the below SQL script. 试试下面的SQL脚本。

First we LAG to find the differences. 首先,我们滞后寻找差异。 Then, we get each transaction and whether there is a difference. 然后,我们获取每笔交易以及是否存在差异。 And finally, we get the percentage. 最后,我们得到了百分比。

DECLARE @MinDate DATE = '2017/04/06',
        @MaxDate DATE = '2017/05/09';

SELECT count(*) AS TotalTransactions
    ,sum(Change) AS TransactionsWithChange
    ,(cast(sum(Change) AS FLOAT) / cast(count(*) AS FLOAT)) AS ChangePercent
FROM (
    SELECT TransDetailID
        ,MAX(classChange) AS Change
    FROM (
        SELECT *
            ,LAG(AVClassID, 1, AVClassID) OVER (
                PARTITION BY TransDetailID ORDER BY AVDetailID
                ) AS PrevClassId
            ,CASE 
                WHEN LAG(AVClassID, 1, AVClassID) OVER (
                        PARTITION BY TransDetailID ORDER BY AVDetailID
                        ) != AVClassID
                    THEN 1
                ELSE 0
                END AS ClassChange
        FROM AVTransDetail
        where CreatedDate between @MinDate and @MaxDate
        ) AS CoreData
    GROUP BY TransDetailID
    ) AS ChangeData

Hope this helps. 希望这可以帮助。

I added more sample rows to get better result 我添加了更多示例行以获得更好的结果

create table #trans (
    AVDetailID int,
    TransDetailID int,
    AVClassID int,
    CamID int,
    CreatedDate datetime
)

insert into #trans values 
( 20101522, 54125478, 5, 1, '2017-05-08 10:15:01:560'),
( 20101523, 54125478, 5, 2, '2017-05-08 10:15:01:620'),
( 20101524, 54125479, 3, 1, '2017-05-08 10:15:03:120'),
( 20101525, 54125479, 2, 2, '2017-05-08 10:15:03:860'),
( 20101526, 54125480, 4, 1, '2017-05-08 10:15:06:330'),
( 20101527, 54125480, 4, 2, '2017-05-08 10:15:06:850'),
( 20101528, 54125481, 4, 1, '2017-05-08 10:15:07:850'),
( 20101529, 54125481, 5, 2, '2017-05-08 10:15:09:850'),
( 20101530, 54125482, 4, 1, '2017-05-08 10:15:07:850'),
( 20101531, 54125482, 5, 3, '2017-05-08 10:15:09:850')

;with diff as (
    -- select records that have different class 
    select CamID as Ent_CamID, count(*) diff_Count
    from #trans ent 
        outer apply (
            select top 1 AVClassID as x_AVClassID, CamID as x_CamID from #trans 
            where CreatedDate > ent.CreatedDate and TransDetailID = ent.TransDetailID
            order by CamID, CreatedDate desc
        ) ext
    where ent.AVClassID <> ext.x_AVClassID
    group by ent.CamID, ext.x_CamID
    union
    select ext.x_CamID as Ext_CamID, count(*) diff_Count
    from #trans ent 
        outer apply (
            select top 1 AVClassID as x_AVClassID, CamID as x_CamID from #trans 
            where CreatedDate > ent.CreatedDate and TransDetailID = ent.TransDetailID
            order by CamID, CreatedDate desc
        ) ext
    where ent.AVClassID <> ext.x_AVClassID
    group by ent.CamID, ext.x_CamID
)
, perc as (
    select Ent_CamID as CamID, sum(diff_Count) Total_Error
    , (select count(*) 
       from #trans where CamID = diff.Ent_CamID 
       group by CamID) AS Total_Capture
    from diff
    group by Ent_CamID
)
select CamID, Total_Error, Total_Capture, 100*(Total_Error)/Total_Capture Error_Percentage
from perc

Result: 结果:

CamID   Total_Error Total_Capture   Error_Percentage
1       3           5               60
2       2           4               50
3       1           1               100

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

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