使用UNPIVOT将代码从SQL重写为Redshift [英] Rewrite code with UNPIVOT from sql to redshift
问题描述
我有需要转换为redshift的SQL Server脚本.
我转换了一部分
这是我遇到问题的脚本的一部分.
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方言中炖制<.具体来说,首先在列的字符串文字名称数组上调用UNNEST
,然后在实际列的数组上再次调用UNNEST
,以在单独的行中返回指标和值.
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
注意:将来,请确保合并一个 Description 值的查找表,您可以将这些ID加入这些表中,并避免冗长的CASE
逻辑计算甚至冗长的IN
子句./p>
I have SQL server script that needs to be converted to redshift.
I converted part of it
Here is part of the script where I have a problem with.
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
All is working, instead of UNPIVOT function.
As I know redshift doesn't have UNPIVOT function.
So now I need to rewrite it correctly?
Thank's for help.
Consider the UNNEST(ARRAY(...))
approach, borrowed from this approach by @Stew from the PostgreSQL dialect which RedShift originally derives. Specifically, first call UNNEST
on array of string literal names of columns and then again on array of actual columns to return indicator and value in separate rows.
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
However, reconsider pivoting and then unpivoting. Simply create your metric column conditionally with CASE
and then aggregate:
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
NOTE: In future, be sure to incorporate a lookup table of Description values that you can join these ids to and avoid the long CASE
logic calculation and even long IN
clause.
这篇关于使用UNPIVOT将代码从SQL重写为Redshift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!