在 sql 服务器中从 SELECT 插入或更新 table
INSERT or UPDATE the table from SELECT in sql server
我有一个要求,我必须检查营业日期的记录是否已经存在于 table 中,然后我需要从 select 语句中更新该营业日期的值,否则我必须从 select 语句中插入该营业日期。以下是我目前只插入的完整查询:
INSERT INTO
gstl_calculated_daily_fee(business_date,fee_type,fee_total,range_id,total_band_count)
select
@tlf_business_date,
'FEE_LOCAL_CARD',
SUM(C.settlement_fees),
C.range_id,
Count(1)
From
(
select
*
from
(
select
rowNumber = @previous_mada_switch_fee_volume_based_count + (ROW_NUMBER() OVER(PARTITION BY DATEPART(MONTH, x_datetime) ORDER BY x_datetime)),
tt.x_datetime
from gstl_trans_temp tt where (message_type_mapping = '0220') and card_type ='GEIDP1' and response_code IN('00','10','11') and tran_amount_req >= 5000 AND merchant_type NOT IN(5542,5541,4829)
) A
CROSS APPLY
(
select
rtt.settlement_fees,
rtt.range_id
From gstl_mada_local_switch_fee_volume_based rtt
where A.rowNumber >= rtt.range_start
AND (A.rowNumber <= rtt.range_end OR rtt.range_end IS NULL)
) B
) C
group by CAST(C.x_datetime AS DATE),C.range_id
我尝试使用 if exists 但无法满足上述完整查询。
if exists (select
business_date
from gstl_calculated_daily_fee
where
business_date = @tlf_business_date)
UPDATE gstl_calculated_daily_fee
SET fee_total = @total_mada_local_switch_fee_low
WHERE fee_type = 'FEE_LOCAL_CARD'
AND business_date = @tlf_business_date
else
INSERT INTO
请帮忙。
您需要一个带连接的 MERGE
语句。
基本上,MERGE
的问题是我们只想合并目标 table 的一个子集。为此,我们将 table 作为 CTE 进行预过滤。我们还可以将源 table 作为 CTE。
在使用 CTE 时写 MERGE
时要非常小心。您必须确保将 CTE 中的目标完全过滤为要合并的行,然后使用 ON
匹配行
;with source as (
select
business_date = @tlf_business_date,
fee_total = SUM(C.settlement_fees),
C.range_id,
total_band_count = Count(1)
From
(
select
rowNumber = @previous_mada_switch_fee_volume_based_count + (ROW_NUMBER() OVER(PARTITION BY DATEPART(MONTH, x_datetime) ORDER BY x_datetime)),
tt.x_datetime
from gstl_trans_temp tt where (message_type_mapping = '0220') and card_type ='GEIDP1' and response_code IN('00','10','11') and tran_amount_req >= 5000 AND merchant_type NOT IN(5542,5541,4829)
) A
CROSS APPLY
(
select
rtt.settlement_fees,
rtt.range_id
From gstl_mada_local_switch_fee_volume_based rtt
where A.rowNumber >= rtt.range_start
AND (A.rowNumber <= rtt.range_end OR rtt.range_end IS NULL)
) B
group by CAST(A.x_datetime AS DATE), B.range_id
),
target as (
select
business_date,fee_type,fee_total,range_id,total_band_count
from gstl_calculated_daily_fee
where business_date = @tlf_business_date AND fee_type = 'FEE_LOCAL_CARD'
)
MERGE INTO target t
USING source s
ON t.business_date = s.business_date AND t.range_id = s.range_id
WHEN NOT MATCHED BY TARGET THEN INSERT
(business_date,fee_type,fee_total,range_id,total_band_count)
VALUES
(s.business_date,'FEE_LOCAL_CARD', s.fee_total, s.range_id, s.total_band_count)
WHEN MATCHED THEN UPDATE SET
fee_total = @total_mada_local_switch_fee_low
;
MERGE
语句的工作方式是,它基本上在源和目标 table 之间执行 FULL JOIN
,使用 ON
子句进行匹配。然后它将各种条件应用于生成的连接并根据它们执行语句。
您可以执行三种可能的条件:
WHEN MATCHED THEN
WHEN NOT MATCHED [BY TARGET] THEN
WHEN NOT MATCHED BY SOURCE THEN
以及三种可能的语句,都指向目标table:UPDATE
、INSERT
、DELETE
(显然不是所有情况都适用)。
一个常见的问题是我们只想考虑目标的一个子集 table。对此有多种可能的解决方案:
我们可以过滤 WHEN MATCHED
子句中的匹配项,例如WHEN MATCHED AND target.somefilter = @somefilter
。不过,这通常会导致完整的 table 扫描。
相反, 我们将过滤后的目标 table 放入 CTE 中,然后 MERGE
放入其中。 CTE 必须遵循 Updatable View 规则。我们还必须 select 我们希望插入或更新的所有列。但是我们必须确保我们完全过滤了目标,否则如果我们发出 DELETE
那么目标 table 中的所有行都将被删除。
我有一个要求,我必须检查营业日期的记录是否已经存在于 table 中,然后我需要从 select 语句中更新该营业日期的值,否则我必须从 select 语句中插入该营业日期。以下是我目前只插入的完整查询:
INSERT INTO
gstl_calculated_daily_fee(business_date,fee_type,fee_total,range_id,total_band_count)
select
@tlf_business_date,
'FEE_LOCAL_CARD',
SUM(C.settlement_fees),
C.range_id,
Count(1)
From
(
select
*
from
(
select
rowNumber = @previous_mada_switch_fee_volume_based_count + (ROW_NUMBER() OVER(PARTITION BY DATEPART(MONTH, x_datetime) ORDER BY x_datetime)),
tt.x_datetime
from gstl_trans_temp tt where (message_type_mapping = '0220') and card_type ='GEIDP1' and response_code IN('00','10','11') and tran_amount_req >= 5000 AND merchant_type NOT IN(5542,5541,4829)
) A
CROSS APPLY
(
select
rtt.settlement_fees,
rtt.range_id
From gstl_mada_local_switch_fee_volume_based rtt
where A.rowNumber >= rtt.range_start
AND (A.rowNumber <= rtt.range_end OR rtt.range_end IS NULL)
) B
) C
group by CAST(C.x_datetime AS DATE),C.range_id
我尝试使用 if exists 但无法满足上述完整查询。
if exists (select
business_date
from gstl_calculated_daily_fee
where
business_date = @tlf_business_date)
UPDATE gstl_calculated_daily_fee
SET fee_total = @total_mada_local_switch_fee_low
WHERE fee_type = 'FEE_LOCAL_CARD'
AND business_date = @tlf_business_date
else
INSERT INTO
请帮忙。
您需要一个带连接的 MERGE
语句。
基本上,MERGE
的问题是我们只想合并目标 table 的一个子集。为此,我们将 table 作为 CTE 进行预过滤。我们还可以将源 table 作为 CTE。
在使用 CTE 时写 MERGE
时要非常小心。您必须确保将 CTE 中的目标完全过滤为要合并的行,然后使用 ON
;with source as (
select
business_date = @tlf_business_date,
fee_total = SUM(C.settlement_fees),
C.range_id,
total_band_count = Count(1)
From
(
select
rowNumber = @previous_mada_switch_fee_volume_based_count + (ROW_NUMBER() OVER(PARTITION BY DATEPART(MONTH, x_datetime) ORDER BY x_datetime)),
tt.x_datetime
from gstl_trans_temp tt where (message_type_mapping = '0220') and card_type ='GEIDP1' and response_code IN('00','10','11') and tran_amount_req >= 5000 AND merchant_type NOT IN(5542,5541,4829)
) A
CROSS APPLY
(
select
rtt.settlement_fees,
rtt.range_id
From gstl_mada_local_switch_fee_volume_based rtt
where A.rowNumber >= rtt.range_start
AND (A.rowNumber <= rtt.range_end OR rtt.range_end IS NULL)
) B
group by CAST(A.x_datetime AS DATE), B.range_id
),
target as (
select
business_date,fee_type,fee_total,range_id,total_band_count
from gstl_calculated_daily_fee
where business_date = @tlf_business_date AND fee_type = 'FEE_LOCAL_CARD'
)
MERGE INTO target t
USING source s
ON t.business_date = s.business_date AND t.range_id = s.range_id
WHEN NOT MATCHED BY TARGET THEN INSERT
(business_date,fee_type,fee_total,range_id,total_band_count)
VALUES
(s.business_date,'FEE_LOCAL_CARD', s.fee_total, s.range_id, s.total_band_count)
WHEN MATCHED THEN UPDATE SET
fee_total = @total_mada_local_switch_fee_low
;
MERGE
语句的工作方式是,它基本上在源和目标 table 之间执行 FULL JOIN
,使用 ON
子句进行匹配。然后它将各种条件应用于生成的连接并根据它们执行语句。
您可以执行三种可能的条件:
WHEN MATCHED THEN
WHEN NOT MATCHED [BY TARGET] THEN
WHEN NOT MATCHED BY SOURCE THEN
以及三种可能的语句,都指向目标table:UPDATE
、INSERT
、DELETE
(显然不是所有情况都适用)。
一个常见的问题是我们只想考虑目标的一个子集 table。对此有多种可能的解决方案:
我们可以过滤 WHEN MATCHED
子句中的匹配项,例如WHEN MATCHED AND target.somefilter = @somefilter
。不过,这通常会导致完整的 table 扫描。
相反, 我们将过滤后的目标 table 放入 CTE 中,然后 MERGE
放入其中。 CTE 必须遵循 Updatable View 规则。我们还必须 select 我们希望插入或更新的所有列。但是我们必须确保我们完全过滤了目标,否则如果我们发出 DELETE
那么目标 table 中的所有行都将被删除。