sql—如果不存在具有相同id和时间戳的其他行,则仅获取具有特定id和时间戳的行

qrjkbowd  于 2021-07-27  发布在  Java
关注(0)|答案(2)|浏览(365)

我使用t-sql从azure数据库导入和转换数据,该数据库用于在powerbi中为我们的客户创建可视化效果。
我得到的是:
包含测量数据的表格。每个数据值都与特定的时间戳、unitid和数据类型相关联。

我想要一张table,里面有:
如果给定unitid和timestamp的未校准电流和视在功率都存在,则只有数据类型视在功率的行。
如果给定unitid和timestamp只存在未校准电流而不存在视在功率,则数据类型为未校准电流的行。
如果在给定的时间戳和单位ID下存在视在功率,那么未校准电流也总是存在的。除上述两种数据类型外,数据集中还有其他数据类型。
为了可视化,我想要一个表,其中只包含下图中用绿色标记的行:


我已经深入研究了这个问题,但我必须承认,我的sql技能仍然太有限,无法找到或创建解决方案。

vmdwslir

vmdwslir1#

嗯。你可以使用窗口功能:

select t.*
from (select t.*,
             sum(case when datatype = 'apparent-power' then 1 else 0 end) over (partition by unitid, timestamp) as cnt_ap,
             sum(case when datatype = 'uncalibrated-current' then 1 else 0 end) over (partition by unitid, timestamp) as cnt_uc
      from t
     ) t
where datatype = 'apparent-power' and cnt_uc > 0 or
      datatype = 'uncalibrated-current' and cnt_ap = 0;

如果我理解正确,你也可以使用 not exists :

select t.*
from t
where t.datatype = 'apparent_power' or
      not exists (select 1
                  from t t2
                  where t2.unitid = t.unitid and
                        t2.timestamp = t.timestamp and
                        t2.datatype = 'apparent_power'
                 );
jchrr9hc

jchrr9hc2#

我认为最好用union将问题分成两部分,all将附加两个表,这样你就可以只关注于获得所有的视在功率,然后只关注未校准的电流
然后就是过滤的任务:

(
    SELECT DISTINCT T1.* 
    FROM T AS T1
    INNER JOIN 
        (SELECT * FROM T WHERE DataType = 'uncalibrated-current') AS T2 
        ON T1.UnitID = T2.UnitID AND T1.TimeStamp = T2.TimeStamp
    WHERE T1.DataType = 'apparent-power'
)
UNION ALL
(
    SELECT DISTINCT T1.*
    FROM T AS T1
    LEFT JOIN 
        (SELECT * FROM T WHERE DataType = 'apparent-power') AS T2 
        ON T1.UnitID = T2.UnitID AND T1.TimeStamp = T2.TimeStamp
    WHERE T1.DataType = 'uncalibrated-current'
        AND T2.DataType IS NULL
)

第一个查询具有 INNER JOIN ,有效地过滤掉任何不匹配的内容。第二个查询称为反连接,过滤掉所有匹配的内容( T2.DataType IS NULL )
最后是 DISTINCT 在这两个表上,都要考虑这样一个事实:如果您的数据类型多于这2个,那么这些连接将复制行

相关问题