SQL“分区”检查无法正常工作

Posted

技术标签:

【中文标题】SQL“分区”检查无法正常工作【英文标题】:SQL "Partition" check not working properly 【发布时间】:2017-06-12 12:29:09 【问题描述】:

我的以下查询工作正常,它根据最新的扫描将新产品注册到不同的位置。

我的问题是,有时我会收到具有相同 ID 的产品(这实际上是可能的)。 在我的下表中有位置,通常当产品到达 位置 5 时,这意味着它已经完成,而当新产品注册时,它将始终从 位置 1 开始。 正如您在下面看到的,我再次获得了产品“2222”,我想让我的下方“FirstScanned”检索 2222', 1, '2017-05-17 15:58 而不是 2222', 1, '2017-03-21 09:50

,min(p.Scanned) over (partition by p.ProductNR) as FirstScanned 

桌子:

CREATE TABLE Products
 (
  ProductNR varchar (14),
  Location int,
  Scanned Datetime
  );
 Insert Into Products(ProductNR, Location, Scanned)
 Values('1111', 1, '2017-03-15 09:30'), 
  ('1111', 2, '2017-03-16 11:35'), 
  ('1111', 3, '2017-03-21 12:37'), 
  ('2222', 1, '2017-03-21 09:50'),
  ('2222', 5, '2017-03-21 12:58');
  ('2222', 1, '2017-05-17 15:58');

和查询

select p.ProductNR, p.Location, p.Scanned
    ,case
        when p.FirstScanned >= dateadd(day, -5, getdate()) then 'Less than 5 days old'
        when p.FirstScanned <= dateadd(day, -5, getdate()) then 'More than 5 days old'
        else '0'
     end as Age
from
(
    select p.ProductNR
        ,p.Location
        ,p.Scanned
        ,min(p.Scanned) over (partition by p.ProductNR) as FirstScanned
        ,max(p.Scanned) over (partition by p.ProductNR) as LastScanned
    from Products p
) p
where p.LastScanned = p.Scanned

【问题讨论】:

测试数据加1,同时添加预期结果和实际结果 谢谢!我所期望的基本上是如果一个新的产品注册到我的表中,它已经具有相同的产品编号。我希望我的查询只检索新的而不是旧的。旧的通常定义为由位置 5 关闭,如上所述,日期也较旧 1111 的输出是什么?没有选择记录,因为没有位置 5 的记录? 1111很好,因为它还没有到达位置5,但是产品2222已在2017-03-21 12:58完成,但在2222', 1, '2017-再次收到05-17 15:58。基本上 min(p.scanned) 现在应该指向 2222', 1, '2017-05-17 15:58 而不是 2222', 1, '2017-03-21 09:50 如果你明白我的意思什么意思? 【参考方案1】:
; WITH p1 AS (
    SELECT p.ProductNR
        ,p.Location
        ,p.Scanned
    FROM #Products p
    WHERE p.Location <> 5
)  
, p2 AS (
    SELECT p2.ProductNR
        ,p2.Location
        ,p2.Scanned
        ,min(p2.Scanned) OVER (PARTITION BY p2.ProductNR) AS FirstScanned
        ,max(p2.Scanned) OVER (PARTITION BY p2.ProductNR) AS LastScanned
    FROM p1 p2
)  

SELECT p3.ProductNR
    , p3.Location
    , p3.Scanned
    , CASE 
        WHEN p3.FirstScanned >= dateadd(day, -5, getdate()) THEN 'Less than 5 days old'
        WHEN p3.FirstScanned <= dateadd(day, -5, getdate()) THEN 'More than 5 days old'
        ELSE '0'
     END AS Age
FROM p2 p3
WHERE p3.LastScanned = p3.Scanned

【讨论】:

您需要在分区之前过滤掉您不想包含的记录。然后对 CTE 执行 CTE 以过滤这些结果。 我明白你的逻辑,我现在试试看!

以上是关于SQL“分区”检查无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

T-SQL 动态枢轴无法正常工作

Ubuntu 16.04开启休眠功能

Dos 命令(如果存在)无法正常工作

Angular:类型检查模板无法正常工作

电脑开机显示windows无法正常启动,是怎么回事呢?

Vetur 在模板中无法正常工作(不检查数据、方法...)