使用 Joined SQL 查询作为另一个 SQL 查询的过滤器
Use Joined SQL query as filter for another SQL query
目前我有一些数据存储在2 table秒Call_log("A"供参考)和PEG_LOG(B供参考)。在 table A 中,它存储有关进入我们系统的呼叫的信息,并为每个呼叫提供一个 callID。在 table B 中,它获取呼叫 ID 并为流程中的每个步骤创建一个新行。要获取所有可用数据,我必须对 A 和 B
进行左连接
Select
Call_Log.IVR_CALL_ID AS CallLogCallID,
Call_Log.CALL_START_DTM AS CallStartTime,
Call_Log.CALL_END_DTM AS CallEndTime,
call_Log.XFER_GROUP AS TransferGroup,
Call_Log.DNIS AS DNIS,
Call_log.ANI AS ANI,
Call_log.XFER_NBR AS TransferNumber,
Call_Log.Caller_data_1 AS CallBackNumber,
Call_Log.Caller_data_2 AS UserID,
Call_Log.Caller_data_3 AS CallerData3,
Call_Log.SERVER AS Server,
Call_Log.PBX_ID AS PBXID,
Call_Log.CTI_ID AS CTIID,
Call_Log.APP AS APP,
Call_Log.LANGUAGE AS LANGUAGE,
Call_Log.XFER_APP AS TransferApp,
Call_Log.XFER_PEG AS TransferPeg,
Call_Log.XFER_STATUS AS TransferStatus,
Call_Log.ON_DUTY_FLAG AS OnDutyFlag,
Call_Log.CALL_HANDLED AS CallHandled,
Call_Log.TRANSFERRED AS Transferred,
PEG_LOG.IVR_CALL_ID AS PEGCallID,
PEG_LOG.SEQ_NBR AS SequenceNumber,
PEG_LOG.APP AS PEGApp,
PEG_LOG.TRANSFERRED AS PEGTransferred,
PEG_LOG.PEG AS PEG,
PEG_LOG.PEG_START_DTM AS PEGStart,
PEG_LOG.PEG_END_DTM AS PEGEnd,
PEG_LOG.RESPONSE AS UserResponse,
PEG_LOG.REQUEST AS Request,
PEG_LOG.RESPONSE_STATUS AS RepsonseStatus
From Call_Log
Left join PEG_LOG ON Call_Log.IVR_CALL_ID = PEG_LOG.IVR_CALL_ID
我需要做的是获取任何通过 Peg 1(peg_log.Peg 作为 peg)的 calllogcallID,然后使用这些 calllogids 作为过滤器提取所有数据
因此,如果呼叫 1 通过挂钩 1 2 3 4 5,呼叫 2 通过挂钩 2 3 4 5,呼叫 3 通过 1 3 4 5,那么我将获得呼叫 1 和 3 的所有数据,但是不适用于通话 2。
我不能只根据通过挂钩 1 的任何呼叫日志进行筛选,因为我需要存储在附加列中的信息,用于其他呼叫通过的挂钩。
这确实超出了我 SQL 的舒适范围,我一直无法找到解决方案。
这些是我要采取的步骤:
- 做一个判断peg_logtable中的seq_nbr是否为1的case语句。如果是,输出1,如果不是,输出0。
- 将此 case 语句包装在 'max' 窗口函数中,由 call_log 上的主键分区(ivr_call_id?),以便在我们的任何一个时输出“1” case 语句命中了 call_log 主键的分组。请注意,窗口函数不会折叠您的数据。所以你仍然会拥有你之前拥有的所有个人记录。我称之为 'hasPegSeq1'.
- 将所有这些包装在一个通用的 table 表达式 (CTE) 中,或者如果您愿意,也可以使用子查询。
- 调用 CTE 中的所有记录,这些记录表明 peg_log 中至少有一行 call_log 为 1。
这里有一些代码代表刚才所说的内容:
with
callAndPegLogs as (
select CallLogCallID = cl.ivr_call_id,
-- other call_log columns here
SequenceNumber = pl.seq_nbr,
-- other peg_log columns here,
hasPegSeq1 =
max(case when pl.seq_nbr = 1 then 1 else 0 end)
over (partition by cl.ivr_call_id)
from call_log cl
left join peg_log pl on cl.ivr_call_id = pl.ivr_call_id
)
select *
from callAndPegLogs cpl
where hasPegSeq1 = 1
请注意,您可以将窗口函数更改为 'min(pl.seq_nbr)' 并获得相同的结果,但是使用 case 语句,如果需要,您可以更轻松地适应其他序列号。
这在 peg=1 的连接中使用了一个子查询。这就是你想要的吗?
Declare @Call_log Table
(
IVR_CALL_ID Int,
otherfield VarChar(50)
)
Insert Into @call_log Values
(1,'xxxxx'),
(2,'yyyy'),
(3,'zzzzz'),
(4,'22222'),
(5,'333333')
Declare @Peg_Log Table
(
Id Int,
IVR_CALL_ID Int,
peg Int
)
Insert Into @Peg_log Values
(1,1,1),
(2,2,1),
(3,1,2),
(4,3,3),
(5,5,1)
Select Distinct c.IVR_CALL_ID
From
@Call_Log c Left join
@PEG_LOG p ON c.IVR_CALL_ID = p.IVR_CALL_ID INNER Join
(Select IVR_CALL_ID From @Peg_Log Where peg =1) x ON c.IVR_CALL_ID = x.IVR_CALL_ID
结果:(删除 Distinct 以获得其他列)
IVR_CALL_ID
-----------
1
2
5
根据@Clockwork-Muse 对我的另一个回答的评论,我将介绍我原来的方法。
老实说,它确实看起来更好,所以我可能会删除我的另一个答案。虽然我很好奇,但如果您想同时测试两者,并让我们知道这种方法实际上是否更快?
select CallLogCallID = cl.ivr_call_id,
-- other call_log columns here
SequenceNumber = pl.seq_nbr,
-- other peg_log columns here
from call_log cl
left join peg_log pl on cl.ivr_call_id = pl.ivr_call_id
where exists (
select 0
from peg_log plSub
where cl.ivr_call_id = plSub.ivr_call_id
and plSub.seq_nbr = 1
)
目前我有一些数据存储在2 table秒Call_log("A"供参考)和PEG_LOG(B供参考)。在 table A 中,它存储有关进入我们系统的呼叫的信息,并为每个呼叫提供一个 callID。在 table B 中,它获取呼叫 ID 并为流程中的每个步骤创建一个新行。要获取所有可用数据,我必须对 A 和 B
进行左连接Select
Call_Log.IVR_CALL_ID AS CallLogCallID,
Call_Log.CALL_START_DTM AS CallStartTime,
Call_Log.CALL_END_DTM AS CallEndTime,
call_Log.XFER_GROUP AS TransferGroup,
Call_Log.DNIS AS DNIS,
Call_log.ANI AS ANI,
Call_log.XFER_NBR AS TransferNumber,
Call_Log.Caller_data_1 AS CallBackNumber,
Call_Log.Caller_data_2 AS UserID,
Call_Log.Caller_data_3 AS CallerData3,
Call_Log.SERVER AS Server,
Call_Log.PBX_ID AS PBXID,
Call_Log.CTI_ID AS CTIID,
Call_Log.APP AS APP,
Call_Log.LANGUAGE AS LANGUAGE,
Call_Log.XFER_APP AS TransferApp,
Call_Log.XFER_PEG AS TransferPeg,
Call_Log.XFER_STATUS AS TransferStatus,
Call_Log.ON_DUTY_FLAG AS OnDutyFlag,
Call_Log.CALL_HANDLED AS CallHandled,
Call_Log.TRANSFERRED AS Transferred,
PEG_LOG.IVR_CALL_ID AS PEGCallID,
PEG_LOG.SEQ_NBR AS SequenceNumber,
PEG_LOG.APP AS PEGApp,
PEG_LOG.TRANSFERRED AS PEGTransferred,
PEG_LOG.PEG AS PEG,
PEG_LOG.PEG_START_DTM AS PEGStart,
PEG_LOG.PEG_END_DTM AS PEGEnd,
PEG_LOG.RESPONSE AS UserResponse,
PEG_LOG.REQUEST AS Request,
PEG_LOG.RESPONSE_STATUS AS RepsonseStatus
From Call_Log
Left join PEG_LOG ON Call_Log.IVR_CALL_ID = PEG_LOG.IVR_CALL_ID
我需要做的是获取任何通过 Peg 1(peg_log.Peg 作为 peg)的 calllogcallID,然后使用这些 calllogids 作为过滤器提取所有数据
因此,如果呼叫 1 通过挂钩 1 2 3 4 5,呼叫 2 通过挂钩 2 3 4 5,呼叫 3 通过 1 3 4 5,那么我将获得呼叫 1 和 3 的所有数据,但是不适用于通话 2。
我不能只根据通过挂钩 1 的任何呼叫日志进行筛选,因为我需要存储在附加列中的信息,用于其他呼叫通过的挂钩。
这确实超出了我 SQL 的舒适范围,我一直无法找到解决方案。
这些是我要采取的步骤:
- 做一个判断peg_logtable中的seq_nbr是否为1的case语句。如果是,输出1,如果不是,输出0。
- 将此 case 语句包装在 'max' 窗口函数中,由 call_log 上的主键分区(ivr_call_id?),以便在我们的任何一个时输出“1” case 语句命中了 call_log 主键的分组。请注意,窗口函数不会折叠您的数据。所以你仍然会拥有你之前拥有的所有个人记录。我称之为 'hasPegSeq1'.
- 将所有这些包装在一个通用的 table 表达式 (CTE) 中,或者如果您愿意,也可以使用子查询。
- 调用 CTE 中的所有记录,这些记录表明 peg_log 中至少有一行 call_log 为 1。
这里有一些代码代表刚才所说的内容:
with
callAndPegLogs as (
select CallLogCallID = cl.ivr_call_id,
-- other call_log columns here
SequenceNumber = pl.seq_nbr,
-- other peg_log columns here,
hasPegSeq1 =
max(case when pl.seq_nbr = 1 then 1 else 0 end)
over (partition by cl.ivr_call_id)
from call_log cl
left join peg_log pl on cl.ivr_call_id = pl.ivr_call_id
)
select *
from callAndPegLogs cpl
where hasPegSeq1 = 1
请注意,您可以将窗口函数更改为 'min(pl.seq_nbr)' 并获得相同的结果,但是使用 case 语句,如果需要,您可以更轻松地适应其他序列号。
这在 peg=1 的连接中使用了一个子查询。这就是你想要的吗?
Declare @Call_log Table
(
IVR_CALL_ID Int,
otherfield VarChar(50)
)
Insert Into @call_log Values
(1,'xxxxx'),
(2,'yyyy'),
(3,'zzzzz'),
(4,'22222'),
(5,'333333')
Declare @Peg_Log Table
(
Id Int,
IVR_CALL_ID Int,
peg Int
)
Insert Into @Peg_log Values
(1,1,1),
(2,2,1),
(3,1,2),
(4,3,3),
(5,5,1)
Select Distinct c.IVR_CALL_ID
From
@Call_Log c Left join
@PEG_LOG p ON c.IVR_CALL_ID = p.IVR_CALL_ID INNER Join
(Select IVR_CALL_ID From @Peg_Log Where peg =1) x ON c.IVR_CALL_ID = x.IVR_CALL_ID
结果:(删除 Distinct 以获得其他列)
IVR_CALL_ID
-----------
1
2
5
根据@Clockwork-Muse 对我的另一个回答的评论,我将介绍我原来的方法。
老实说,它确实看起来更好,所以我可能会删除我的另一个答案。虽然我很好奇,但如果您想同时测试两者,并让我们知道这种方法实际上是否更快?
select CallLogCallID = cl.ivr_call_id,
-- other call_log columns here
SequenceNumber = pl.seq_nbr,
-- other peg_log columns here
from call_log cl
left join peg_log pl on cl.ivr_call_id = pl.ivr_call_id
where exists (
select 0
from peg_log plSub
where cl.ivr_call_id = plSub.ivr_call_id
and plSub.seq_nbr = 1
)