如何解决具有复杂业务规则的 CROSS JOINS 或 UNION ALL?
我之所以创建这个是因为我对答案很好奇。
我有一个基本上有 4 列的表格:GroupA、GroupB、Tag 和 value。
A组 | B组 | 标签 | 价值 |
---|---|---|---|
A | E | PrefixYear3.SubCategoryASubSubcategoryA | 100 |
B | F | PrefixYear3.SubCategoryBSubSubcategoryA | A |
C | G | PrefixYear4.SubCategoryCSubSubcategoryZ | 300 |
我知道 Year3 是 2010 年,Year4 是 2011 年等等,我有一个特定标签的列表,而不是在表格中,以及它们匹配的类别(一个标签可以属于多个类别)。
我需要返回一个包含以下内容的表格:
子类别A | 子类别B | 子类别C | 年 | 类别 |
---|---|---|---|---|
1000 | 2000 | 2900 | 2010 | A |
... | ... | ... | ... | ... |
1550 | 0 | 450 | 2020 | C |
我正在尝试改进的查询具有以下算法:
SELECT GROUPA,GROUPB,SUM(
CASE WHEN Tag in ('PrefixYear3.SubCategoryASubSubcategoryA') THEN TRY_CAST([Value] as float)END)
) as SubCategoryA,...,'2010' AS Year
'CategoryA' AS Category
GROUP BY GroupA,GroupB
UNION ALL
...
UNION ALL
SELECT GROUPA,SUM(
CASE WHEN Tag in ('PrefixYear5.SubCategoryASubSubcategoryA') THEN
TRY_CAST([Value] as float)END) as SubCategoryA,'2012' AS Year
'CategoryA' AS Category
GROUP BY GroupA,GroupB
我发现这样做的方法比那个解决方案要多得多(三倍):
SELECT A.GROUPA,A.GROUPB,CASE C.Category
WHEN 'A' THEN
CASE B.Year WHEN 2010 THEN [2010 SubCategoryA CategoryA]
...
CASE B.Year WHEN 2012 THEN [2012 SubCategoryA CategoryA]
END AS [SubCategoryA]
...
CASE C.Category
WHEN 'C' THEN
CASE B.Year WHEN 2010 THEN [2010 SubCategoryC CategoryA]
...
CASE B.Year WHEN 2012 THEN [2012 SubCategoryC CategoryA]
END AS [SubCategoryC]
B.Year,C.Category FROM
(
SELECT GROUPA,sum(CASE WHEN Tag in ('PrefixYear3.SubCategoryASubSubcategoryA') THEN TRY_CAST([Value] as float)END) AS '2010 SubCategoryA CategoryA',...
sum(CASE WHEN Tag in ('PrefixYear5.SubCategoryASubSubcategoryA') THEN TRY_CAST([Value] as float)END) AS '2012 SubCategoryA CategoryA'
FROM TableA GROUP BY GROUPA,GROUPB)
CROSS JOIN (SELECT '2010' as [Year]
UNION
SELECT '2011'
...) as B
CROSS JOIN (SELECT 'CategoryA' as [Category]
UNION SELECT 'CategoryB'
...) AS C
答案应该是视图。这意味着没有临时表或创建其他表是有效的答案。
关于如何更好地做到这一点的任何建议表示赞赏。提前致谢!
解决方法
您的示例数据与显示的预期结果不匹配,因此需要进行一些猜测,特别是对于未包含在所提供数据中的 category
,但我相信您可以通过以下方式获得所需数据:
CREATE TABLE mytable(
GroupA VARCHAR(1) NOT NULL,Group_B VARCHAR(1) NOT NULL,Tag VARCHAR(39) NOT NULL,Value VARCHAR(3) NOT NULL
);
INSERT INTO mytable(GroupA,Group_B,Tag,Value) VALUES ('A','E','PrefixYear3.SubCategoryASubSubcategoryA','100');
INSERT INTO mytable(GroupA,Value) VALUES ('B','F','PrefixYear3.SubCategoryBSubSubcategoryA','A');
INSERT INTO mytable(GroupA,Value) VALUES ('C','G','PrefixYear4.SubCategoryCSubSubcategoryZ','300');
然后这个查询:
select
SubCategoryA,SubCategoryB,SubCategoryC,Year,GroupA as Category
from (
select
*,case when tag like '%.SubCategoryA%' then try_cast(value as float) end as SubCategoryA,case when tag like '%.SubCategoryB%' then try_cast(value as float) end as SubCategoryB,case when tag like '%.SubCategoryC%' then try_cast(value as float) end as SubCategoryC,case when tag like 'PrefixYear3%' then 2010
when tag like 'PrefixYear4%' then 2011
else NULL
end as [Year]
from mytable
) as sq
产生这个输出:
+--------------+--------------+--------------+------+----------+
| SubCategoryA | SubCategoryB | SubCategoryC | Year | Category |
+--------------+--------------+--------------+------+----------+
| 100 | | | 2010 | A |
| | | | 2010 | B |
| | | 300 | 2011 | C |
+--------------+--------------+--------------+------+----------+
在 dbfiddle here
注意:我使用了 try_cast()
,因为如果它无法从 varchar 值返回浮点数,它将优雅地返回 NULL。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。