用 UNPIVOT 重写代码,从 sql 到 redshift
Rewrite code with UNPIVOT from sql to redshift
我有 SQL 个服务器脚本需要转换为 redshift。
我转换了一部分
这是我遇到问题的部分脚本。
SELECT a.*,
b.*
FROM (
SELECT u.ContactId,
u.Description,
CONVERT(Float,u.SeatCharge) AS SeatCharge
--CAST(u.SeatCharge AS numeric (18,4)) AS SeatCharge,
--CONVERT(INT, CASE WHEN IsNumeric(CONVERT(VARCHAR(12), u.SeatCharge)) = 1 then CONVERT(VARCHAR(12), u.SeatCharge) else 0 End)
FROM(
SELECT md.contactid,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7172 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Core,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7182 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_RCM,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7192 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Advanced_RCM,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7183 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Payroll,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7184 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_DXM,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7185 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Messaging,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7186 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Tasks,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7173 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Core,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7187 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Data_Collection,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7189 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Auditing_Tools,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7190 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Group_Sessions,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7191 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_ABC_Data,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7211 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_AGA,
CONVERT(float, MAX(CASE WHEN md.fieldid= 4495 THEN CONVERT(float,Value) ELSE 0 END)) AS LMS_Core,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7175 THEN CONVERT(float,Value) ELSE 0 END)) AS HRIS_PTO,
CONVERT(float, MAX(CASE WHEN md.fieldid= 8106 THEN CONVERT(float,Value) ELSE 0 END)) AS LMS_Course_Groups,
CONVERT(float, MAX(CASE WHEN md.fieldid= 8286 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Reach_Me,
CONVERT(float, MAX(CASE WHEN md.fieldid= 8999 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Redshift,
CONVERT(float, MAX(CASE WHEN md.fieldid= 9155 THEN CONVERT(float,Value) ELSE 0 END)) AS HRIS_Benefits,
CONVERT(float, MAX(CASE WHEN md.fieldid= 9156 THEN CONVERT(float,Value) ELSE 0 END)) AS HRIS_Assets
FROM public.contact_meta md
WHERE md.fieldid IN (4495,7172,7182,7192,7183,7184,7185,7186,7173,7187,7189,7190,7191,7175,7211,7212,8106,8286,8999,9155,9156)
--AND md.ContactId = 75337
GROUP BY
md.contactid
)s
--UNPIVOT
--(
--SeatCharge
--FOR Description IN (
-- PM_Core,
-- PM_RCM,
-- PM_Advanced_RCM,
-- PM_Payroll,
-- PM_DXM,
-- PM_Messaging,
-- PM_Tasks,
--HRIS_Assets)
--)u
WHERE u.SeatCharge <> ''
)a
一切正常,而不是 UNPIVOT 功能。
据我所知,redshift 没有 UNPIVOT 功能。
那么现在我需要正确地重写它吗?
感谢您的帮助。
考虑 UNNEST(ARRAY(...))
方法,从 RedShift 最初派生的 PostgreSQL 方言中借用 approach by @Stew。具体来说,首先在列的字符串文字名称数组上调用 UNNEST
,然后在实际列数组上再次调用 return 指标和单独行中的值。
SELECT s.ContactId,
UNNEST(ARRAY('PM_Core', 'PM_RCM', 'PM_Advanced_RCM', 'PM_Payroll', 'PM_DXM',
'PM_Messaging', 'PM_Tasks', 'Clinical_Core', 'Clinical_Data_Collection',
'Clinical_Auditing_Tools', 'Clinical_Group_Sessions', 'Clinical_Group_Sessions',
'Clinical_ABC_Data', 'Clinical_AGA', 'LMS_Core', 'HRIS_PTO', 'LMS_Course_Groups',
'PM_Reach_Me', 'PM_Redshift', 'HRIS_Benefits', 'HRIS_Assets')) AS Description,
UNNEST(ARRAY(PM_Core, PM_RCM, PM_Advanced_RCM, PM_Payroll, PM_DXM,
PM_Messaging, PM_Tasks, Clinical_Core, Clinical_Data_Collection,
Clinical_Auditing_Tools, Clinical_Group_Sessions, Clinical_Group_Sessions,
Clinical_ABC_Data, Clinical_AGA, LMS_Core, HRIS_PTO, LMS_Course_Groups,
PM_Reach_Me, PM_Redshift, HRIS_Benefits, HRIS_Assets)) AS SeatCharge
FROM
(SELECT md.contactid,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7172 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Core,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7182 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_RCM,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7192 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Advanced_RCM,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7183 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Payroll,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7184 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_DXM,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7185 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Messaging,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7186 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Tasks,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7173 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Core,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7187 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Data_Collection,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7189 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Auditing_Tools,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7190 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Group_Sessions,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7191 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_ABC_Data,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7211 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_AGA,
CONVERT(float, MAX(CASE WHEN md.fieldid= 4495 THEN CONVERT(float,Value) ELSE 0 END)) AS LMS_Core,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7175 THEN CONVERT(float,Value) ELSE 0 END)) AS HRIS_PTO,
CONVERT(float, MAX(CASE WHEN md.fieldid= 8106 THEN CONVERT(float,Value) ELSE 0 END)) AS LMS_Course_Groups,
CONVERT(float, MAX(CASE WHEN md.fieldid= 8286 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Reach_Me,
CONVERT(float, MAX(CASE WHEN md.fieldid= 8999 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Redshift,
CONVERT(float, MAX(CASE WHEN md.fieldid= 9155 THEN CONVERT(float,Value) ELSE 0 END)) AS HRIS_Benefits,
CONVERT(float, MAX(CASE WHEN md.fieldid= 9156 THEN CONVERT(float,Value) ELSE 0 END)) AS HRIS_Assets
FROM public.contact_meta md
WHERE md.fieldid IN (4495,7172,7182,7192,7183,7184,7185,7186,7173,7187,7189,7190,7191,7175,7211,7212,8106,8286,8999,9155,9156)
--AND md.ContactId = 75337
GROUP BY
md.contactid
) s
但是,请重新考虑旋转然后取消旋转。只需使用 CASE
有条件地创建您的指标列,然后聚合:
SELECT sub.contactid, sub.Description, MAX(sub."VALUE") As SeatCharge
FROM
(SELECT md.contactid,
CASE md.fieldid
WHEN 7172 THEN 'PM_Core'
WHEN 7182 THEN 'PM_RCM'
WHEN 7192 THEN 'PM_Advanced_RCM'
WHEN 7183 THEN 'PM_Payroll'
WHEN 7184 THEN 'PM_DXM'
WHEN 7185 THEN 'PM_Messaging'
WHEN 7186 THEN 'PM_Tasks'
WHEN 7173 THEN 'Clinical_Core'
WHEN 7187 THEN 'Clinical_Data_Collection'
WHEN 7189 THEN 'Clinical_Auditing_Tools'
WHEN 7190 THEN 'Clinical_Group_Sessions'
WHEN 7191 THEN 'Clinical_ABC_Data'
WHEN 7211 THEN 'Clinical_AGA'
WHEN 4495 THEN 'LMS_Core'
WHEN 7175 THEN 'HRIS_PTO'
WHEN 8106 THEN 'LMS_Course_Groups'
WHEN 8286 THEN 'PM_Reach_Me'
WHEN 8999 THEN 'PM_Redshift'
WHEN 9155 THEN 'HRIS_Benefits'
WHEN 9156 THEN 'HRIS_Assets'
ELSE NULL
END AS Description,
CONVERT(float, Value) AS VALUE
FROM public.contact_meta md
WHERE md.fieldid IN (4495, 7172, 7182, 7192, 7183, 7184,7185, 7186, 7173, 7187, 7189,
7190, 7191, 7175, 7211, 7212,8106, 8286, 8999, 9155, 9156)
--AND md.ContactId = 75337
) AS sub
GROUP BY sub.contactid, sub.Description
注意:将来,请务必合并 描述 值的查找 table,您可以将这些 ID 加入其中,避免长 CASE
逻辑计算甚至长IN
子句。
我有 SQL 个服务器脚本需要转换为 redshift。
我转换了一部分
这是我遇到问题的部分脚本。
SELECT a.*,
b.*
FROM (
SELECT u.ContactId,
u.Description,
CONVERT(Float,u.SeatCharge) AS SeatCharge
--CAST(u.SeatCharge AS numeric (18,4)) AS SeatCharge,
--CONVERT(INT, CASE WHEN IsNumeric(CONVERT(VARCHAR(12), u.SeatCharge)) = 1 then CONVERT(VARCHAR(12), u.SeatCharge) else 0 End)
FROM(
SELECT md.contactid,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7172 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Core,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7182 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_RCM,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7192 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Advanced_RCM,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7183 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Payroll,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7184 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_DXM,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7185 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Messaging,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7186 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Tasks,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7173 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Core,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7187 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Data_Collection,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7189 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Auditing_Tools,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7190 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Group_Sessions,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7191 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_ABC_Data,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7211 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_AGA,
CONVERT(float, MAX(CASE WHEN md.fieldid= 4495 THEN CONVERT(float,Value) ELSE 0 END)) AS LMS_Core,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7175 THEN CONVERT(float,Value) ELSE 0 END)) AS HRIS_PTO,
CONVERT(float, MAX(CASE WHEN md.fieldid= 8106 THEN CONVERT(float,Value) ELSE 0 END)) AS LMS_Course_Groups,
CONVERT(float, MAX(CASE WHEN md.fieldid= 8286 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Reach_Me,
CONVERT(float, MAX(CASE WHEN md.fieldid= 8999 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Redshift,
CONVERT(float, MAX(CASE WHEN md.fieldid= 9155 THEN CONVERT(float,Value) ELSE 0 END)) AS HRIS_Benefits,
CONVERT(float, MAX(CASE WHEN md.fieldid= 9156 THEN CONVERT(float,Value) ELSE 0 END)) AS HRIS_Assets
FROM public.contact_meta md
WHERE md.fieldid IN (4495,7172,7182,7192,7183,7184,7185,7186,7173,7187,7189,7190,7191,7175,7211,7212,8106,8286,8999,9155,9156)
--AND md.ContactId = 75337
GROUP BY
md.contactid
)s
--UNPIVOT
--(
--SeatCharge
--FOR Description IN (
-- PM_Core,
-- PM_RCM,
-- PM_Advanced_RCM,
-- PM_Payroll,
-- PM_DXM,
-- PM_Messaging,
-- PM_Tasks,
--HRIS_Assets)
--)u
WHERE u.SeatCharge <> ''
)a
一切正常,而不是 UNPIVOT 功能。
据我所知,redshift 没有 UNPIVOT 功能。
那么现在我需要正确地重写它吗?
感谢您的帮助。
考虑 UNNEST(ARRAY(...))
方法,从 RedShift 最初派生的 PostgreSQL 方言中借用 approach by @Stew。具体来说,首先在列的字符串文字名称数组上调用 UNNEST
,然后在实际列数组上再次调用 return 指标和单独行中的值。
SELECT s.ContactId,
UNNEST(ARRAY('PM_Core', 'PM_RCM', 'PM_Advanced_RCM', 'PM_Payroll', 'PM_DXM',
'PM_Messaging', 'PM_Tasks', 'Clinical_Core', 'Clinical_Data_Collection',
'Clinical_Auditing_Tools', 'Clinical_Group_Sessions', 'Clinical_Group_Sessions',
'Clinical_ABC_Data', 'Clinical_AGA', 'LMS_Core', 'HRIS_PTO', 'LMS_Course_Groups',
'PM_Reach_Me', 'PM_Redshift', 'HRIS_Benefits', 'HRIS_Assets')) AS Description,
UNNEST(ARRAY(PM_Core, PM_RCM, PM_Advanced_RCM, PM_Payroll, PM_DXM,
PM_Messaging, PM_Tasks, Clinical_Core, Clinical_Data_Collection,
Clinical_Auditing_Tools, Clinical_Group_Sessions, Clinical_Group_Sessions,
Clinical_ABC_Data, Clinical_AGA, LMS_Core, HRIS_PTO, LMS_Course_Groups,
PM_Reach_Me, PM_Redshift, HRIS_Benefits, HRIS_Assets)) AS SeatCharge
FROM
(SELECT md.contactid,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7172 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Core,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7182 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_RCM,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7192 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Advanced_RCM,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7183 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Payroll,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7184 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_DXM,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7185 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Messaging,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7186 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Tasks,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7173 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Core,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7187 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Data_Collection,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7189 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Auditing_Tools,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7190 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_Group_Sessions,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7191 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_ABC_Data,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7211 THEN CONVERT(float,Value) ELSE 0 END)) AS Clinical_AGA,
CONVERT(float, MAX(CASE WHEN md.fieldid= 4495 THEN CONVERT(float,Value) ELSE 0 END)) AS LMS_Core,
CONVERT(float, MAX(CASE WHEN md.fieldid= 7175 THEN CONVERT(float,Value) ELSE 0 END)) AS HRIS_PTO,
CONVERT(float, MAX(CASE WHEN md.fieldid= 8106 THEN CONVERT(float,Value) ELSE 0 END)) AS LMS_Course_Groups,
CONVERT(float, MAX(CASE WHEN md.fieldid= 8286 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Reach_Me,
CONVERT(float, MAX(CASE WHEN md.fieldid= 8999 THEN CONVERT(float,Value) ELSE 0 END)) AS PM_Redshift,
CONVERT(float, MAX(CASE WHEN md.fieldid= 9155 THEN CONVERT(float,Value) ELSE 0 END)) AS HRIS_Benefits,
CONVERT(float, MAX(CASE WHEN md.fieldid= 9156 THEN CONVERT(float,Value) ELSE 0 END)) AS HRIS_Assets
FROM public.contact_meta md
WHERE md.fieldid IN (4495,7172,7182,7192,7183,7184,7185,7186,7173,7187,7189,7190,7191,7175,7211,7212,8106,8286,8999,9155,9156)
--AND md.ContactId = 75337
GROUP BY
md.contactid
) s
但是,请重新考虑旋转然后取消旋转。只需使用 CASE
有条件地创建您的指标列,然后聚合:
SELECT sub.contactid, sub.Description, MAX(sub."VALUE") As SeatCharge
FROM
(SELECT md.contactid,
CASE md.fieldid
WHEN 7172 THEN 'PM_Core'
WHEN 7182 THEN 'PM_RCM'
WHEN 7192 THEN 'PM_Advanced_RCM'
WHEN 7183 THEN 'PM_Payroll'
WHEN 7184 THEN 'PM_DXM'
WHEN 7185 THEN 'PM_Messaging'
WHEN 7186 THEN 'PM_Tasks'
WHEN 7173 THEN 'Clinical_Core'
WHEN 7187 THEN 'Clinical_Data_Collection'
WHEN 7189 THEN 'Clinical_Auditing_Tools'
WHEN 7190 THEN 'Clinical_Group_Sessions'
WHEN 7191 THEN 'Clinical_ABC_Data'
WHEN 7211 THEN 'Clinical_AGA'
WHEN 4495 THEN 'LMS_Core'
WHEN 7175 THEN 'HRIS_PTO'
WHEN 8106 THEN 'LMS_Course_Groups'
WHEN 8286 THEN 'PM_Reach_Me'
WHEN 8999 THEN 'PM_Redshift'
WHEN 9155 THEN 'HRIS_Benefits'
WHEN 9156 THEN 'HRIS_Assets'
ELSE NULL
END AS Description,
CONVERT(float, Value) AS VALUE
FROM public.contact_meta md
WHERE md.fieldid IN (4495, 7172, 7182, 7192, 7183, 7184,7185, 7186, 7173, 7187, 7189,
7190, 7191, 7175, 7211, 7212,8106, 8286, 8999, 9155, 9156)
--AND md.ContactId = 75337
) AS sub
GROUP BY sub.contactid, sub.Description
注意:将来,请务必合并 描述 值的查找 table,您可以将这些 ID 加入其中,避免长 CASE
逻辑计算甚至长IN
子句。