我试图通过整个s_date
/ part_no
分组中的结果CASE语句填充具有相同结果值的列。
我们尝试了多种不同的途径来使递归能够满足我们的需求,但是没有运气。计算非常棘手,并且我们知道SQL并不是递归的最佳选择,因此我们正试图找到一种替代途径,暂时满足客户需求和时间紧迫。
SELECT
s_date,
part_no,
i_group,
s_level,
p_category,
qty_filled,
qty_total,
relief_amt,
extreme_amt,
curr_mth_note,
CASE
WHEN curr_mth_note IS NOT NULL
AND i_group = '1'
AND s_level = '80' THEN qty_filled
ELSE NULL
END AS g1s1_filled
FROM
(
SELECT
t1.s_date,
t1.part_no,
t1.i_group,
t1.s_level,
t1.p_category,
t1.qty_filled,
t1.qty_total,
mv.relief_amt,
mv.extreme_amt,
mv.curr_mth_note,
FROM
multi_table mv,
t_table t1
WHERE
t1.part_no = mv.part_no
AND mv.part_no = 'xxxx'
AND t1.s_date = mv.s_date
AND t1.s_date = '201805'
GROUP BY
t1.s_date,
t1.i_group,
t1.s_level,
t1.part_no,
t1.p_category,
t1.qty_filled,
t1.qty_total,
mv.relief_amt,
mv.extreme_amt,
mv.curr_mth_note,
ORDER BY
t1.s_date,
t1.i_group,
t1.s_level DESC
)
ORDER BY
s_date,
part_no,
i_group,
DECODE(s_level, '80', 1, '100', 2, 'Late', 3)
以上内容的当前输出如下:
我要/希望得到的是整个g1s1_filled
列,以显示相同的67金额,其中i_group = '1' and s_level = '80'
用于所有可用的日期/部分组合。
因此该列应显示以下内容:
G1S1_FILLED
67
67
67
67
67
我研究了如何尝试在没有运气的情况下使用where而不是when。 这样会有很多其他的列,我最终也可以在这些列上进行计算。
答案 0 :(得分:2)
您可以在SELECT
子句中使用条件分析最小值。我没有您的数据,因此我将在SCOTT.EMP
表上进行类似的查询来说明-假设我想用一位特定员工的薪水填补NEWCOL
。我会这样:
select empno, ename, sal, job, deptno,
min(case when empno = 7499 and ename = 'ALLEN' then sal end) over () as newcol
from scott.emp;
EMPNO ENAME SAL JOB DEPTNO NEWCOL
---------- ---------- ---------- --------- ---------- ----------
7369 SMITH 800 CLERK 20 1600
7499 ALLEN 1600 SALESMAN 30 1600
7521 WARD 1250 SALESMAN 30 1600
7566 JONES 2975 MANAGER 20 1600
7654 MARTIN 1250 SALESMAN 30 1600
7698 BLAKE 2850 MANAGER 30 1600
7782 CLARK 2450 MANAGER 10 1600
7788 SCOTT 3000 ANALYST 20 1600
7839 KING 5000 PRESIDENT 10 1600
7844 TURNER 1500 SALESMAN 30 1600
7876 ADAMS 1100 CLERK 20 1600
7900 JAMES 950 CLERK 30 1600
7902 FORD 3000 ANALYST 20 1600
7934 MILLER 1300 CLERK 10 1600
如果(在您遇到的问题中)I_GROUP
和S_LEVEL
中只有一行包含值的“特殊”组合,则可以使用(有条件的,分析的)MIN
或MAX
甚至AVG
或SUM
-它们都等于单个值,在您的情况下为67。如果有多个这样的值,那么您将需要做出选择:您想要MIN
,MAX
,AVG
还是其他东西。无论如何,您仍然可以使用相同的想法。
答案 1 :(得分:2)
我认为您想要一个窗口函数:
SUM(CASE WHEN curr_mth_note IS NOT NULL AND i_group = '1' AND
s_level = '80'
THEN qty_filled
END) OVER (PARTITION BY s_date, part_no) AS g1s1_filled
答案 2 :(得分:0)
代替case语句,为其编写一个子查询
(select qty_filled
from t_Table
where
i_group = '1' and
s_level = '80' and
rownum = 1
) as g1s1_filled
答案 3 :(得分:0)
您可以删除CASE
表达式并将整个查询(ORDER BY
子句除外)移至CTE。然后,您可以自我JOIN
,将相关的g1s1_filled
附加到每一行。
注意:定义自连接条件时必须小心;我在下面提供了一个建议,您可能需要对其进行完善。
查询:
WITH cte AS (
SELECT
s_date,
part_no,
i_group,
s_level,
p_category,
qty_filled,
qty_total,
relief_amt,
extreme_amt,
curr_mth_note
FROM
(
SELECT
t1.s_date,
t1.part_no,
t1.i_group,
t1.s_level,
t1.p_category,
t1.qty_filled,
t1.qty_total,
mv.relief_amt,
mv.extreme_amt,
mv.curr_mth_note,
FROM
multi_table mv,
t_table t1
WHERE
t1.part_no = mv.part_no
AND mv.part_no = 'xxxx'
AND t1.s_date = mv.s_date
AND t1.s_date = '201805'
GROUP BY
t1.s_date,
t1.i_group,
t1.s_level,
t1.part_no,
t1.p_category,
t1.qty_filled,
t1.qty_total,
mv.relief_amt,
mv.extreme_amt,
mv.curr_mth_note,
ORDER BY
t1.s_date,
t1.i_group,
t1.s_level DESC
)
)
SELECT a.*, b.qty_filled as g1s1_filled
FROM
cte AS a
INNER JOIN cte as b
ON b.s_date = a.s_date
AND b.part_no = a.part_no
AND b.i_group = '1'
AND b.s_level = '80'
AND b.curr_mth_note IS NOT NULL
ORDER BY
a.s_date,
a.part_no,
a.i_group,
DECODE(a.s_level, '80', 1, '100', 2, 'Late', 3)