SQL 带 COALESCE 的条件 SELECT(分组或 table 连接可能存在问题)
SQL Conditional SELECT with COALESCE (possible issue with grouping or table joins)
提前为问题的长度道歉:
我正在处理一个查询,以显示将从不同表中提取的数据,具体取决于请求数据的设施。
我们维护着来自各个产品线的许多统计数据,每个设施都希望能够查看生产线级别的数据;然而,一些机构还按部门对产品进行分组,然后甚至按 "value stream"(只是层次结构中的另一层)对部门进行分组。
我想做的是在可用的最高组中显示数据(具有价值流的设施获取该设施的流列表,只有产品线的设施查看产品列表,等等) ).
我已经使用 COALESCE 函数来帮助解决这个问题,因为我有兴趣测试 NULL 值以确定设施使用的组织组。
不幸的是,必要的数据位于 6 个不同的表中,需要进行几次连接。我为每个连接添加了额外的参数以尝试确保连接正确。
对于不使用流或部门的设施(下例中的 1),查询功能正常;生成产品列表及其各自的分数。
查询未提供其他级别的所需结果。对于使用价值流 (2) 组织的设施,期望的结果是该设施的流及其各自分数的列表。相反,会再次生成产品线列表。
这是我的查询:
select * from
(select a.*, rownum rnum from (
SELECT /*STREAM_ID, DEPT_ID ,LINE,*/
COALESCE(VS.ID, DT.ID, SLR.LINE) "ID",
COALESCE(VS.NAME, DT.NAME, SLR.NAME) "NAME",
case when SAFETY_VALUE = 0 then 'GREEN' when SAFETY_VALUE > 0 then 'RED' else 'WHITE' end AS COLOR
FROM XX_SQDC_LINES_REF SLR
LEFT JOIN SQDC_DEPARTMENT_DETAILS DTD on SLR.SITE=DTD.FACILITY_ID AND SLR.LINE=DTD.LINE_ID
LEFT JOIN SQDC_VALUE_STREAM_DETAILS VSD ON DTD.FACILITY_ID= VSD.FACILITY_ID AND DTD.LINE_ID=VSD.LINE_ID
LEFT JOIN SQDC_SAFETY_MAX KPI ON VSD.FACILITY_ID=KPI.FACILITY_ID AND VSD.LINE_ID=KPI.LINE_ID
LEFT JOIN SQDC_DEPARTMENTS DT ON KPI.FACILITY_ID= DT.FACILITY_ID and dtd.dept_id=dt.id
LEFT JOIN SQDC_VALUE_STREAMS VS ON DT.FACILITY_ID= VS.FACILITY_ID AND DT.VS_ID=VS.ID
WHERE (SITE = 2)
ORDER by NAME
)a)
表(示例值;还有一些我遗漏的列,因为它们与此查询无关):
XX_SQDC_LINES_REF
Line Name Site
1 Table 1
2 Lamp 1
3 Screen 2
4 Forcep 2
5 Brush 2
6 Camera2 2
7 Screen2 2
8 Forcep2 2
9 Brush2 2
10 Camera2 2
SQDC_DEPARTMENT_DETAILS
Dept_ID Line_ID Facility_ID
1 3 2
1 4 2
2 5 2
2 6 2
3 7 2
3 8 2
4 9 2
4 10 2
SQDC_VALUE_STREAM_DETAILS
Stream_ID Line_ID Facility_ID
1 3 2
1 4 2
1 5 2
1 6 2
2 7 2
2 8 2
2 9 2
2 10 2
SQDC_SAFETY_MAX
Facility_ID Line_ID Actual_Date Safety_Value
1 1 31-Jan-16 0
1 2 31-Jan-16 0
2 3 31-Jan-16 0
2 4 24-Jan-16 10
2 5 24-Jan-16 0
2 7 24-Jan-16 0
2 9 24-Jan-16 0
SQDC_DEPARTMENTS
ID Name Facility_ID VS_ID
1 Dept 1 2 1
2 Dept 2 2 1
3 Dept 3 2 2
4 Dept 4 2 2
SQDC_VALUE_STREAMS
ID Name Facility_ID
1 VS 1 2
2 VS 2 2
提前感谢任何能帮助我指明正确方向的人。
编辑以添加预期结果:
站点 1(无流):
ID Name Color RNUM
1 Table GREEN 1
2 Lamp GREEN 2
站点 2(带流):
ID Name Color RNUM
1 VS 1 GREEN 1
2 VS 2 WHITE 2
我知道我缺少一些额外的函数或运算符来使它按照我喜欢的方式工作,所以让我们看看我是否可以重新表述期望:
我想显示设施使用的最高级别(流、部门或产品)的 ID、名称和安全值颜色代码,并在最近一天提供了信息。
根据 VS 和部门表,站点 1 没有任何流或部门,因此应该填充产品列表。使用提供的数据,站点 1 将单独显示两种产品并显示绿色值,因为两种产品数据均来自 2016 年 1 月 31 日且值为 0。如果站点 1 下有其他产品包含该日期之前的数据,则颜色将无论实际安全值如何,都为白色。
站点 2 最好显示仅包含两个价值流的列表(因为这是最高级别)。
站点 2 的最晚日期是 2016 年 1 月 31 日。在 VS 1 下的产品线中,只有 Line_ID=3 有这个日期(其他线有更早的日期)。因此,平均安全值将为 0(Line_ID=4 的 10 由于日期较早,不会成为平均值的一部分),然后颜色为绿色。
VS 2 下所有产品线的安全值均在 2016 年 1 月 31 日之前,因此未计算平均值,因此结果为白色。
希望这有助于解决问题。
来自@Hogan 的每个请求的单个案例查询:
价值流级别查询(如网站 2):
select *
from
(select a.*, rownum rnum
from
(SELECT stream_id, NAME, case when SUM(SAFETY_VALUE) = 0 then 'GREEN' when SUM(SAFETY_VALUE) > 0 then 'RED' else 'WHITE' end AS COLOR
FROM SQDC_VALUE_STREAMS VLS LEFT JOIN SQDC_VALUE_STREAM_DETAILS VS ON VLS.ID = VS.STREAM_ID LEFT JOIN SQDC_SAFETY_MAX KPI ON VS.LINE_ID=KPI.LINE_ID
WHERE (vs.facility_id = 2
)
group by name, STREAM_id
ORDER by NAME) a
)
部门级查询(示例中没有这样的站点,但它会以相同的方式工作):
select *
from
(select a.*, rownum rnum
from
(SELECT dept_id, NAME, case when SUM(SAFETY_VALUE) = 0 then 'GREEN' when SUM(SAFETY_VALUE) > 0 then 'RED' else 'WHITE' end AS COLOR
FROM SQDC_DEPARTMENTS DPTS LEFT JOIN SQDC_DEPARTMENT_DETAILS DT ON DPTS.ID = DT.Dept_ID LEFT JOIN SQDC_SAFETY_MAX KPI ON DT.LINE_ID=KPI.LINE_ID
WHERE (DT.facility_id = 7986128121911792
)
group by name, DEPT_id
ORDER by NAME) a
)
产品级别查询(如站点 1):
select *
from
(select a.*, rownum rnum
from
(SELECT line, NAME, case when SAFETY_VALUE = 0 then 'GREEN' when SAFETY_VALUE > 0 then 'RED' else 'WHITE' end AS COLOR
FROM XX_SQDC_LINES_REF SLR LEFT JOIN SQDC_SAFETY_MAX KPI ON SLR.LINE=KPI.LINE_ID
WHERE (SITE = 1
)
ORDER by NAME) a
)
目标是将这三个查询合并为一个,并确保只显示设施的最高组织级别(流、部门、产品)。
鉴于您的 3 个查询,不难将它们与您描述的规则合并。
我知道,这不像 COALESCE 和许多花哨的连接那样性感,但我认为这可能是最好的方法,因为它非常清晰,因此易于维护。
WITH stream_query AS
(
SELECT 1 AS PRIORITY, stream_id, null as dept_id, null as line, NAME, COLOR, rownum rnum
FROM (
SELECT stream_id, NAME, case when SUM(SAFETY_VALUE) = 0 then 'GREEN' when SUM(SAFETY_VALUE) > 0 then 'RED' else 'WHITE' end AS COLOR
FROM SQDC_VALUE_STREAMS VLS
LEFT JOIN SQDC_VALUE_STREAM_DETAILS VS ON VLS.ID = VS.STREAM_ID
LEFT JOIN SQDC_SAFETY_MAX KPI ON VS.LINE_ID=KPI.LINE_ID
WHERE vs.facility_id = 2
group by name, STREAM_id
ORDER by NAME
) a
), dept_query AS
(
SELECT 2 AS PRIORITY, null as stream_id, dept_id, null as line, NAME, COLOR, rownum rnum
FROM (
SELECT dept_id, NAME, case when SUM(SAFETY_VALUE) = 0 then 'GREEN' when SUM(SAFETY_VALUE) > 0 then 'RED' else 'WHITE' end AS COLOR
FROM SQDC_DEPARTMENTS DPTS
LEFT JOIN SQDC_DEPARTMENT_DETAILS DT ON DPTS.ID = DT.Dept_ID
LEFT JOIN SQDC_SAFETY_MAX KPI ON DT.LINE_ID=KPI.LINE_ID
WHERE DT.facility_id = 7986128121911792
group by name, DEPT_id
ORDER by NAME
) a
), prod_query AS
(
SELECT 3 AS PRIORITY, null as stream_id, null as dept_id, line, NAME, COLOR, rownum rnum
FROM (
SELECT line, NAME, case when SAFETY_VALUE = 0 then 'GREEN' when SAFETY_VALUE > 0 then 'RED' else 'WHITE' end AS COLOR
FROM XX_SQDC_LINES_REF SLR
LEFT JOIN SQDC_SAFETY_MAX KPI ON SLR.LINE=KPI.LINE_ID
WHERE SITE = 1
ORDER by NAME
) a
), merged AS
(
SELECT a.*, MIN(PRIORITY) OVER () AS HIGHEST
FROM (
SELECT * FROM stream_query
UNION ALL
SELECT * FROM dept_query
UNION ALL
SELECT * FROM prod_query
) a
)
SELECT *
FROM merged
WHERE PRIORITY = HIGHEST
您的想法已找到,但您没有正确设置联接。您需要从 XX_SQDC_LINES_REF 或 SQDC_DEPARTMENT_DETAILS 离开加入——您没有这样做,您是加入到之前的加入
SELECT /*STREAM_ID, DEPT_ID ,LINE,*/
COALESCE(VS.ID, DT.ID, SLR.LINE) "ID",
COALESCE(VS.NAME, DT.NAME, SLR.NAME) "NAME",
case when SAFETY_VALUE = 0 then 'GREEN' when SAFETY_VALUE > 0 then 'RED' else 'WHITE' end AS COLOR,
rownum rnum
FROM XX_SQDC_LINES_REF SLR
LEFT JOIN SQDC_DEPARTMENT_DETAILS DTD on SLR.SITE=DTD.FACILITY_ID AND SLR.LINE=DTD.LINE_ID
LEFT JOIN SQDC_VALUE_STREAM_DETAILS VSD ON SLR.SITE=VSD.FACILITY_ID AND SLR.LINE=VSD.LINE_ID
LEFT JOIN SQDC_SAFETY_MAX KPI ON SLR.SITE=KPI.FACILITY_ID AND SLR.LINE=KPI.LINE_ID
LEFT JOIN SQDC_DEPARTMENTS DT ON SLR.SITE=DT.FACILITY_ID and DTD.dept_id=DT.id
LEFT JOIN SQDC_VALUE_STREAMS VS ON SLR.SITE=VS.FACILITY_ID AND DTD.VS_ID=VS.ID
WHERE (SITE = 2)
ORDER by NAME
我还删除了所有子查询内容,因为那不是必需的,只会让它变得更复杂 (IMO)
在@Hogan 的帮助下,这里是完成的查询:
SELECT COALESCE(STREAM_ID, DEPT_ID, TO_CHAR(LINE)) ID, NAME,COLOR
FROM(
WITH stream_query AS
(
SELECT 1 AS PRIORITY, stream_id, null as dept_id, null as line, NAME, COLOR, rownum rnum
FROM (
SELECT stream_id, NAME, case when SUM(SAFETY_VALUE) = 0 then 'GREEN' when SUM(SAFETY_VALUE) > 0 then 'RED' else 'WHITE' end AS COLOR
FROM SQDC_VALUE_STREAMS VLS
LEFT JOIN SQDC_VALUE_STREAM_DETAILS VS ON VLS.ID = VS.STREAM_ID
LEFT JOIN (select line_id, safety_value, actual_date from SQDC_SAFETY_MAX where actual_date in (select max(actual_date) from SQDC_SAFETY_MAX)) KPI ON VS.LINE_ID=KPI.LINE_ID
WHERE vs.facility_id = [replace1]
group by name, STREAM_id
ORDER by NAME
) a
), dept_query AS
(
SELECT 2 AS PRIORITY, null as stream_id, dept_id, null as line, NAME, COLOR, rownum rnum
FROM (
SELECT dept_id, NAME, case when SUM(SAFETY_VALUE) = 0 then 'GREEN' when SUM(SAFETY_VALUE) > 0 then 'RED' else 'WHITE' end AS COLOR
FROM SQDC_DEPARTMENTS DPTS
LEFT JOIN SQDC_DEPARTMENT_DETAILS DT ON DPTS.ID = DT.Dept_ID
LEFT JOIN (select line_id, safety_value, actual_date from SQDC_SAFETY_MAX where actual_date in (select max(actual_date) from SQDC_SAFETY_MAX)) KPI ON DT.LINE_ID=KPI.LINE_ID
WHERE DT.facility_id = [replace1]
group by name, DEPT_id
ORDER by NAME
) a
), prod_query AS
(
SELECT 3 AS PRIORITY, null as stream_id, null as dept_id, line, NAME, COLOR, rownum rnum
FROM (
SELECT line, NAME, case when SAFETY_VALUE = 0 then 'GREEN' when SAFETY_VALUE > 0 then 'RED' else 'WHITE' end AS COLOR
FROM XX_SQDC_LINES_REF SLR
LEFT JOIN SQDC_SAFETY_MAX KPI ON SLR.LINE=KPI.LINE_ID
WHERE SITE =[replace1]
ORDER by NAME
) a
),merged AS
(
SELECT a.*, MIN(PRIORITY) OVER () AS HIGHEST
FROM (
SELECT * FROM stream_query
UNION ALL
SELECT * FROM dept_query
UNION ALL
SELECT * FROM prod_query
) a
)
SELECT *
FROM merged
WHERE PRIORITY = HIGHEST
)
where rownum <=12
AND rnum >=1
我在 select 中添加了更多内容以获取最新的可用日期并限制行数和列数,但这对测试用例和我的实际数据都有效。再次感谢@Hogan。
提前为问题的长度道歉:
我正在处理一个查询,以显示将从不同表中提取的数据,具体取决于请求数据的设施。
我们维护着来自各个产品线的许多统计数据,每个设施都希望能够查看生产线级别的数据;然而,一些机构还按部门对产品进行分组,然后甚至按 "value stream"(只是层次结构中的另一层)对部门进行分组。
我想做的是在可用的最高组中显示数据(具有价值流的设施获取该设施的流列表,只有产品线的设施查看产品列表,等等) ).
我已经使用 COALESCE 函数来帮助解决这个问题,因为我有兴趣测试 NULL 值以确定设施使用的组织组。
不幸的是,必要的数据位于 6 个不同的表中,需要进行几次连接。我为每个连接添加了额外的参数以尝试确保连接正确。
对于不使用流或部门的设施(下例中的 1),查询功能正常;生成产品列表及其各自的分数。
查询未提供其他级别的所需结果。对于使用价值流 (2) 组织的设施,期望的结果是该设施的流及其各自分数的列表。相反,会再次生成产品线列表。
这是我的查询:
select * from
(select a.*, rownum rnum from (
SELECT /*STREAM_ID, DEPT_ID ,LINE,*/
COALESCE(VS.ID, DT.ID, SLR.LINE) "ID",
COALESCE(VS.NAME, DT.NAME, SLR.NAME) "NAME",
case when SAFETY_VALUE = 0 then 'GREEN' when SAFETY_VALUE > 0 then 'RED' else 'WHITE' end AS COLOR
FROM XX_SQDC_LINES_REF SLR
LEFT JOIN SQDC_DEPARTMENT_DETAILS DTD on SLR.SITE=DTD.FACILITY_ID AND SLR.LINE=DTD.LINE_ID
LEFT JOIN SQDC_VALUE_STREAM_DETAILS VSD ON DTD.FACILITY_ID= VSD.FACILITY_ID AND DTD.LINE_ID=VSD.LINE_ID
LEFT JOIN SQDC_SAFETY_MAX KPI ON VSD.FACILITY_ID=KPI.FACILITY_ID AND VSD.LINE_ID=KPI.LINE_ID
LEFT JOIN SQDC_DEPARTMENTS DT ON KPI.FACILITY_ID= DT.FACILITY_ID and dtd.dept_id=dt.id
LEFT JOIN SQDC_VALUE_STREAMS VS ON DT.FACILITY_ID= VS.FACILITY_ID AND DT.VS_ID=VS.ID
WHERE (SITE = 2)
ORDER by NAME
)a)
表(示例值;还有一些我遗漏的列,因为它们与此查询无关):
XX_SQDC_LINES_REF
Line Name Site
1 Table 1
2 Lamp 1
3 Screen 2
4 Forcep 2
5 Brush 2
6 Camera2 2
7 Screen2 2
8 Forcep2 2
9 Brush2 2
10 Camera2 2
SQDC_DEPARTMENT_DETAILS
Dept_ID Line_ID Facility_ID
1 3 2
1 4 2
2 5 2
2 6 2
3 7 2
3 8 2
4 9 2
4 10 2
SQDC_VALUE_STREAM_DETAILS
Stream_ID Line_ID Facility_ID
1 3 2
1 4 2
1 5 2
1 6 2
2 7 2
2 8 2
2 9 2
2 10 2
SQDC_SAFETY_MAX
Facility_ID Line_ID Actual_Date Safety_Value
1 1 31-Jan-16 0
1 2 31-Jan-16 0
2 3 31-Jan-16 0
2 4 24-Jan-16 10
2 5 24-Jan-16 0
2 7 24-Jan-16 0
2 9 24-Jan-16 0
SQDC_DEPARTMENTS
ID Name Facility_ID VS_ID
1 Dept 1 2 1
2 Dept 2 2 1
3 Dept 3 2 2
4 Dept 4 2 2
SQDC_VALUE_STREAMS
ID Name Facility_ID
1 VS 1 2
2 VS 2 2
提前感谢任何能帮助我指明正确方向的人。
编辑以添加预期结果:
站点 1(无流):
ID Name Color RNUM
1 Table GREEN 1
2 Lamp GREEN 2
站点 2(带流):
ID Name Color RNUM
1 VS 1 GREEN 1
2 VS 2 WHITE 2
我知道我缺少一些额外的函数或运算符来使它按照我喜欢的方式工作,所以让我们看看我是否可以重新表述期望:
我想显示设施使用的最高级别(流、部门或产品)的 ID、名称和安全值颜色代码,并在最近一天提供了信息。
根据 VS 和部门表,站点 1 没有任何流或部门,因此应该填充产品列表。使用提供的数据,站点 1 将单独显示两种产品并显示绿色值,因为两种产品数据均来自 2016 年 1 月 31 日且值为 0。如果站点 1 下有其他产品包含该日期之前的数据,则颜色将无论实际安全值如何,都为白色。
站点 2 最好显示仅包含两个价值流的列表(因为这是最高级别)。
站点 2 的最晚日期是 2016 年 1 月 31 日。在 VS 1 下的产品线中,只有 Line_ID=3 有这个日期(其他线有更早的日期)。因此,平均安全值将为 0(Line_ID=4 的 10 由于日期较早,不会成为平均值的一部分),然后颜色为绿色。
VS 2 下所有产品线的安全值均在 2016 年 1 月 31 日之前,因此未计算平均值,因此结果为白色。
希望这有助于解决问题。
来自@Hogan 的每个请求的单个案例查询:
价值流级别查询(如网站 2):
select *
from
(select a.*, rownum rnum
from
(SELECT stream_id, NAME, case when SUM(SAFETY_VALUE) = 0 then 'GREEN' when SUM(SAFETY_VALUE) > 0 then 'RED' else 'WHITE' end AS COLOR
FROM SQDC_VALUE_STREAMS VLS LEFT JOIN SQDC_VALUE_STREAM_DETAILS VS ON VLS.ID = VS.STREAM_ID LEFT JOIN SQDC_SAFETY_MAX KPI ON VS.LINE_ID=KPI.LINE_ID
WHERE (vs.facility_id = 2
)
group by name, STREAM_id
ORDER by NAME) a
)
部门级查询(示例中没有这样的站点,但它会以相同的方式工作):
select *
from
(select a.*, rownum rnum
from
(SELECT dept_id, NAME, case when SUM(SAFETY_VALUE) = 0 then 'GREEN' when SUM(SAFETY_VALUE) > 0 then 'RED' else 'WHITE' end AS COLOR
FROM SQDC_DEPARTMENTS DPTS LEFT JOIN SQDC_DEPARTMENT_DETAILS DT ON DPTS.ID = DT.Dept_ID LEFT JOIN SQDC_SAFETY_MAX KPI ON DT.LINE_ID=KPI.LINE_ID
WHERE (DT.facility_id = 7986128121911792
)
group by name, DEPT_id
ORDER by NAME) a
)
产品级别查询(如站点 1):
select *
from
(select a.*, rownum rnum
from
(SELECT line, NAME, case when SAFETY_VALUE = 0 then 'GREEN' when SAFETY_VALUE > 0 then 'RED' else 'WHITE' end AS COLOR
FROM XX_SQDC_LINES_REF SLR LEFT JOIN SQDC_SAFETY_MAX KPI ON SLR.LINE=KPI.LINE_ID
WHERE (SITE = 1
)
ORDER by NAME) a
)
目标是将这三个查询合并为一个,并确保只显示设施的最高组织级别(流、部门、产品)。
鉴于您的 3 个查询,不难将它们与您描述的规则合并。
我知道,这不像 COALESCE 和许多花哨的连接那样性感,但我认为这可能是最好的方法,因为它非常清晰,因此易于维护。
WITH stream_query AS
(
SELECT 1 AS PRIORITY, stream_id, null as dept_id, null as line, NAME, COLOR, rownum rnum
FROM (
SELECT stream_id, NAME, case when SUM(SAFETY_VALUE) = 0 then 'GREEN' when SUM(SAFETY_VALUE) > 0 then 'RED' else 'WHITE' end AS COLOR
FROM SQDC_VALUE_STREAMS VLS
LEFT JOIN SQDC_VALUE_STREAM_DETAILS VS ON VLS.ID = VS.STREAM_ID
LEFT JOIN SQDC_SAFETY_MAX KPI ON VS.LINE_ID=KPI.LINE_ID
WHERE vs.facility_id = 2
group by name, STREAM_id
ORDER by NAME
) a
), dept_query AS
(
SELECT 2 AS PRIORITY, null as stream_id, dept_id, null as line, NAME, COLOR, rownum rnum
FROM (
SELECT dept_id, NAME, case when SUM(SAFETY_VALUE) = 0 then 'GREEN' when SUM(SAFETY_VALUE) > 0 then 'RED' else 'WHITE' end AS COLOR
FROM SQDC_DEPARTMENTS DPTS
LEFT JOIN SQDC_DEPARTMENT_DETAILS DT ON DPTS.ID = DT.Dept_ID
LEFT JOIN SQDC_SAFETY_MAX KPI ON DT.LINE_ID=KPI.LINE_ID
WHERE DT.facility_id = 7986128121911792
group by name, DEPT_id
ORDER by NAME
) a
), prod_query AS
(
SELECT 3 AS PRIORITY, null as stream_id, null as dept_id, line, NAME, COLOR, rownum rnum
FROM (
SELECT line, NAME, case when SAFETY_VALUE = 0 then 'GREEN' when SAFETY_VALUE > 0 then 'RED' else 'WHITE' end AS COLOR
FROM XX_SQDC_LINES_REF SLR
LEFT JOIN SQDC_SAFETY_MAX KPI ON SLR.LINE=KPI.LINE_ID
WHERE SITE = 1
ORDER by NAME
) a
), merged AS
(
SELECT a.*, MIN(PRIORITY) OVER () AS HIGHEST
FROM (
SELECT * FROM stream_query
UNION ALL
SELECT * FROM dept_query
UNION ALL
SELECT * FROM prod_query
) a
)
SELECT *
FROM merged
WHERE PRIORITY = HIGHEST
您的想法已找到,但您没有正确设置联接。您需要从 XX_SQDC_LINES_REF 或 SQDC_DEPARTMENT_DETAILS 离开加入——您没有这样做,您是加入到之前的加入
SELECT /*STREAM_ID, DEPT_ID ,LINE,*/
COALESCE(VS.ID, DT.ID, SLR.LINE) "ID",
COALESCE(VS.NAME, DT.NAME, SLR.NAME) "NAME",
case when SAFETY_VALUE = 0 then 'GREEN' when SAFETY_VALUE > 0 then 'RED' else 'WHITE' end AS COLOR,
rownum rnum
FROM XX_SQDC_LINES_REF SLR
LEFT JOIN SQDC_DEPARTMENT_DETAILS DTD on SLR.SITE=DTD.FACILITY_ID AND SLR.LINE=DTD.LINE_ID
LEFT JOIN SQDC_VALUE_STREAM_DETAILS VSD ON SLR.SITE=VSD.FACILITY_ID AND SLR.LINE=VSD.LINE_ID
LEFT JOIN SQDC_SAFETY_MAX KPI ON SLR.SITE=KPI.FACILITY_ID AND SLR.LINE=KPI.LINE_ID
LEFT JOIN SQDC_DEPARTMENTS DT ON SLR.SITE=DT.FACILITY_ID and DTD.dept_id=DT.id
LEFT JOIN SQDC_VALUE_STREAMS VS ON SLR.SITE=VS.FACILITY_ID AND DTD.VS_ID=VS.ID
WHERE (SITE = 2)
ORDER by NAME
我还删除了所有子查询内容,因为那不是必需的,只会让它变得更复杂 (IMO)
在@Hogan 的帮助下,这里是完成的查询:
SELECT COALESCE(STREAM_ID, DEPT_ID, TO_CHAR(LINE)) ID, NAME,COLOR
FROM(
WITH stream_query AS
(
SELECT 1 AS PRIORITY, stream_id, null as dept_id, null as line, NAME, COLOR, rownum rnum
FROM (
SELECT stream_id, NAME, case when SUM(SAFETY_VALUE) = 0 then 'GREEN' when SUM(SAFETY_VALUE) > 0 then 'RED' else 'WHITE' end AS COLOR
FROM SQDC_VALUE_STREAMS VLS
LEFT JOIN SQDC_VALUE_STREAM_DETAILS VS ON VLS.ID = VS.STREAM_ID
LEFT JOIN (select line_id, safety_value, actual_date from SQDC_SAFETY_MAX where actual_date in (select max(actual_date) from SQDC_SAFETY_MAX)) KPI ON VS.LINE_ID=KPI.LINE_ID
WHERE vs.facility_id = [replace1]
group by name, STREAM_id
ORDER by NAME
) a
), dept_query AS
(
SELECT 2 AS PRIORITY, null as stream_id, dept_id, null as line, NAME, COLOR, rownum rnum
FROM (
SELECT dept_id, NAME, case when SUM(SAFETY_VALUE) = 0 then 'GREEN' when SUM(SAFETY_VALUE) > 0 then 'RED' else 'WHITE' end AS COLOR
FROM SQDC_DEPARTMENTS DPTS
LEFT JOIN SQDC_DEPARTMENT_DETAILS DT ON DPTS.ID = DT.Dept_ID
LEFT JOIN (select line_id, safety_value, actual_date from SQDC_SAFETY_MAX where actual_date in (select max(actual_date) from SQDC_SAFETY_MAX)) KPI ON DT.LINE_ID=KPI.LINE_ID
WHERE DT.facility_id = [replace1]
group by name, DEPT_id
ORDER by NAME
) a
), prod_query AS
(
SELECT 3 AS PRIORITY, null as stream_id, null as dept_id, line, NAME, COLOR, rownum rnum
FROM (
SELECT line, NAME, case when SAFETY_VALUE = 0 then 'GREEN' when SAFETY_VALUE > 0 then 'RED' else 'WHITE' end AS COLOR
FROM XX_SQDC_LINES_REF SLR
LEFT JOIN SQDC_SAFETY_MAX KPI ON SLR.LINE=KPI.LINE_ID
WHERE SITE =[replace1]
ORDER by NAME
) a
),merged AS
(
SELECT a.*, MIN(PRIORITY) OVER () AS HIGHEST
FROM (
SELECT * FROM stream_query
UNION ALL
SELECT * FROM dept_query
UNION ALL
SELECT * FROM prod_query
) a
)
SELECT *
FROM merged
WHERE PRIORITY = HIGHEST
)
where rownum <=12
AND rnum >=1
我在 select 中添加了更多内容以获取最新的可用日期并限制行数和列数,但这对测试用例和我的实际数据都有效。再次感谢@Hogan。