SQL 从不相关的表中查看
SQL view from unrelated tables
我有一个包含以下 table 的数据库:
位置信息
DeviceID | MsgDate | MeasureDate | MsgType
---------+---------+-------------+--------
1000 | 15/10/20| 12/10/20 | 1
1000 | 15/10/20| 15/10/20 | 1
1000 | 16/10/20| 16/10/20 | 2
1000 | 17/10/20| 12/10/20 | 3
1001 | 15/10/20| 12/10/20 | 1
1001 | 15/10/20| 15/10/20 | 1
1001 | 15/10/20| 15/10/20 | 3
1002 | 16/10/20| 12/10/20 | 2
温度信息
DeviceID | MsgDate | MeasureDate | MsgType
---------+---------+-------------+--------
1000 | 17/10/20| 12/10/20 | 4
1000 | 17/10/20| 17/10/20 | 4
1000 | 18/10/20| 17/10/20 | 5
1000 | 14/10/20| 14/10/20 | 4
1001 | 15/10/20| 15/10/20 | 4
1001 | 16/10/20| 15/10/20 | 5
1001 | 18/10/20| 16/10/20 | 5
1002 | 18/10/20| 18/10/20 | 5
我总共有大约 4 个类似的 table。每个设备都可以发送将进入这 4 table 之一并填充它们的消息类型。
我想要实现的是获得 SQL 视图(以提供 Power BI 报告),其中 table 看起来像:
DeviceID | MsgType | Delayed | Quantity
---------+---------+---------+--------
1000 | 1 | Yes | 250
1000 | 1 | No | 14
1000 | 2 | Yes | 421
1000 | 2 | No | 51
1000 | 3 | Yes | 320
1000 | 3 | No | 84
1000 | 4 | Yes | 112
1000 | 4 | No | 54
1001 | 1 | Yes | 244
1001 | 1 | No | 36
在这个 table 中,我想为每个设备获取每种类型的消息计数,并且我还想区分实时发送的消息数量和实时发送的消息数量延迟一段时间后发送(无论延迟是多少,只要它不为零即可)。
到目前为止,我已经能够仅基于一个原始 table 创建这样一个 table,请求如下:
SELECT DeviceID, MsgType, DATEDIFF(minute, MeasureDate, MsgDate) AS [Delay], COUNT(*) as Quantity FROM PositionMessages
WHERE MeasureDate = MsgDate
GROUP BY DeviceID, MsgType, DATEDIFF(minute, MeasureDate, MsgDate)
ORDER BY DeviceID ASC
(那将 return 只有“实时消息”,其广播日期等于测量日期)。
这给了我 table :
DeviceID | MsgType | Delayed | Quantity
---------+---------+---------+--------
1000 | 1 | No | 14
1000 | 2 | No | 51
1000 | 3 | No | 84
1001 | 1 | No | 36
1001 | 2 | No | 28
我有另一个延迟消息的请求,好像我按时差对它们进行分组,但它们没有正确收集:
SELECT DeviceID, MsgType, 1 AS [Delay], COUNT(*) as Total FROM PositionMessages
WHERE MeasureDate <> MsgDate
GROUP BY DeviceID, MsgType
ORDER BY DeviceID ASC
这导致 table :
DeviceID | MsgType | Delayed | Quantity
---------+---------+---------+--------
1000 | 1 | Yes | 250
1000 | 2 | Yes | 421
1000 | 3 | Yes | 320
1001 | 1 | Yes | 112
1001 | 2 | Yes | 244
您知道这是否是正确的处理方式吗?我如何将结果放在一个 table 中(连同其他 table 的结果)?
当我尝试包含 UNION ALL 或不同的 JOIN 类型时,出现错误“关键字 'UNION' 附近的语法不正确”。我也不确定如何将它包含在一个视图中,它将通过 SQL 代理每天调用。
非常感谢。
要合并来自多个表的数据,您需要对它们进行 UNION 是正确的。
要对它们进行 UNION,它们之间需要完全相同的列布局和列类型。将它放在视图中非常有效,因为这样您就可以轻松地查询它,并执行您的 WHERE 和您有什么。
对于本委员会来说,这是否是“正确”的处理方式是一个过于宽泛的问题。只有您知道您的业务需求。如果您需要有关特定查询的帮助,我们很乐意提供帮助——但您必须告诉我们它应该是什么样子,以及目前 貌似。我不知道如何帮助您进行第二个查询,因为我不知道您希望它看起来像什么。您是否尝试通过 DeviceID 收集总延迟?
SELECT DeviceID, MsgType, DATEDIFF(minute, MeasureDate, MsgDate) AS [Delay], COUNT(*) as Quantity
FROM A
WHERE MeasureDate = MsgDate
GROUP BY DeviceID, MsgType, DATEDIFF(minute, MeasureDate, MsgDate)
/* Note: your MeasureDate = MsgDate, so doing DATEDIFF is really superfluous unless there's a time component we don't see in your sample */
UNION ALL
SELECT DeviceID, MsgType, SUM(DATEDIFF(minute, MeasureDate, MsgDate)) AS [Delay], COUNT(1) as Total
FROM A
WHERE MeasureDate <> MsgDate
GROUP BY DeviceID, MsgType
ORDER BY DeviceID ASC
Demo here一起玩。请随时制作您自己的示例,然后回来分享它与您的预期结果集,以便我们提供更多帮助。
这似乎是 union all
和聚合:
select DeviceID, MsgType,
(case when MsgDate = MeasureDate then 'No' else 'Yes' end) as delayed,
count(*)
from ((select DeviceID, MsgDate, MeasureDate, MsgType
from PositionMessages
) union all
(select DeviceID, MsgDate, MeasureDate, MsgType
from LocationMessages
)
) m
group by DeviceID,
(case when MsgDate = MeasureDate then 'No' else 'Yes' end),
MsgType;
我有一个包含以下 table 的数据库:
位置信息
DeviceID | MsgDate | MeasureDate | MsgType
---------+---------+-------------+--------
1000 | 15/10/20| 12/10/20 | 1
1000 | 15/10/20| 15/10/20 | 1
1000 | 16/10/20| 16/10/20 | 2
1000 | 17/10/20| 12/10/20 | 3
1001 | 15/10/20| 12/10/20 | 1
1001 | 15/10/20| 15/10/20 | 1
1001 | 15/10/20| 15/10/20 | 3
1002 | 16/10/20| 12/10/20 | 2
温度信息
DeviceID | MsgDate | MeasureDate | MsgType
---------+---------+-------------+--------
1000 | 17/10/20| 12/10/20 | 4
1000 | 17/10/20| 17/10/20 | 4
1000 | 18/10/20| 17/10/20 | 5
1000 | 14/10/20| 14/10/20 | 4
1001 | 15/10/20| 15/10/20 | 4
1001 | 16/10/20| 15/10/20 | 5
1001 | 18/10/20| 16/10/20 | 5
1002 | 18/10/20| 18/10/20 | 5
我总共有大约 4 个类似的 table。每个设备都可以发送将进入这 4 table 之一并填充它们的消息类型。
我想要实现的是获得 SQL 视图(以提供 Power BI 报告),其中 table 看起来像:
DeviceID | MsgType | Delayed | Quantity
---------+---------+---------+--------
1000 | 1 | Yes | 250
1000 | 1 | No | 14
1000 | 2 | Yes | 421
1000 | 2 | No | 51
1000 | 3 | Yes | 320
1000 | 3 | No | 84
1000 | 4 | Yes | 112
1000 | 4 | No | 54
1001 | 1 | Yes | 244
1001 | 1 | No | 36
在这个 table 中,我想为每个设备获取每种类型的消息计数,并且我还想区分实时发送的消息数量和实时发送的消息数量延迟一段时间后发送(无论延迟是多少,只要它不为零即可)。
到目前为止,我已经能够仅基于一个原始 table 创建这样一个 table,请求如下:
SELECT DeviceID, MsgType, DATEDIFF(minute, MeasureDate, MsgDate) AS [Delay], COUNT(*) as Quantity FROM PositionMessages
WHERE MeasureDate = MsgDate
GROUP BY DeviceID, MsgType, DATEDIFF(minute, MeasureDate, MsgDate)
ORDER BY DeviceID ASC
(那将 return 只有“实时消息”,其广播日期等于测量日期)。
这给了我 table :
DeviceID | MsgType | Delayed | Quantity
---------+---------+---------+--------
1000 | 1 | No | 14
1000 | 2 | No | 51
1000 | 3 | No | 84
1001 | 1 | No | 36
1001 | 2 | No | 28
我有另一个延迟消息的请求,好像我按时差对它们进行分组,但它们没有正确收集:
SELECT DeviceID, MsgType, 1 AS [Delay], COUNT(*) as Total FROM PositionMessages
WHERE MeasureDate <> MsgDate
GROUP BY DeviceID, MsgType
ORDER BY DeviceID ASC
这导致 table :
DeviceID | MsgType | Delayed | Quantity
---------+---------+---------+--------
1000 | 1 | Yes | 250
1000 | 2 | Yes | 421
1000 | 3 | Yes | 320
1001 | 1 | Yes | 112
1001 | 2 | Yes | 244
您知道这是否是正确的处理方式吗?我如何将结果放在一个 table 中(连同其他 table 的结果)?
当我尝试包含 UNION ALL 或不同的 JOIN 类型时,出现错误“关键字 'UNION' 附近的语法不正确”。我也不确定如何将它包含在一个视图中,它将通过 SQL 代理每天调用。
非常感谢。
要合并来自多个表的数据,您需要对它们进行 UNION 是正确的。
要对它们进行 UNION,它们之间需要完全相同的列布局和列类型。将它放在视图中非常有效,因为这样您就可以轻松地查询它,并执行您的 WHERE 和您有什么。
对于本委员会来说,这是否是“正确”的处理方式是一个过于宽泛的问题。只有您知道您的业务需求。如果您需要有关特定查询的帮助,我们很乐意提供帮助——但您必须告诉我们它应该是什么样子,以及目前 貌似。我不知道如何帮助您进行第二个查询,因为我不知道您希望它看起来像什么。您是否尝试通过 DeviceID 收集总延迟?
SELECT DeviceID, MsgType, DATEDIFF(minute, MeasureDate, MsgDate) AS [Delay], COUNT(*) as Quantity
FROM A
WHERE MeasureDate = MsgDate
GROUP BY DeviceID, MsgType, DATEDIFF(minute, MeasureDate, MsgDate)
/* Note: your MeasureDate = MsgDate, so doing DATEDIFF is really superfluous unless there's a time component we don't see in your sample */
UNION ALL
SELECT DeviceID, MsgType, SUM(DATEDIFF(minute, MeasureDate, MsgDate)) AS [Delay], COUNT(1) as Total
FROM A
WHERE MeasureDate <> MsgDate
GROUP BY DeviceID, MsgType
ORDER BY DeviceID ASC
Demo here一起玩。请随时制作您自己的示例,然后回来分享它与您的预期结果集,以便我们提供更多帮助。
这似乎是 union all
和聚合:
select DeviceID, MsgType,
(case when MsgDate = MeasureDate then 'No' else 'Yes' end) as delayed,
count(*)
from ((select DeviceID, MsgDate, MeasureDate, MsgType
from PositionMessages
) union all
(select DeviceID, MsgDate, MeasureDate, MsgType
from LocationMessages
)
) m
group by DeviceID,
(case when MsgDate = MeasureDate then 'No' else 'Yes' end),
MsgType;