这是这个问题的后续问题:How do I need to change my sql to get what I want in this case?
我有两张表如下:
Table 1
id id2 date
1 2 2015-01-10
2 5 2015-06-13
3 9 2015-09-05
4 10 2015-02-11
5 26 2015-01-10
6 65 2015-01-25
Table 2
id id2 data(varchar2)
1 2 A
2 5 A
3 9 A
4 10 B
5 26 B
6 65 B
Table 2
中的数据属于varchar2类型,其中包含N
个数字,由,
分隔,其中N
可能依赖于id2
。例如,A
可能是这样的:
1.0,1.1,1.2,1.3,1.4,1.5,2.6,2.7,2.8,2.9, ...(ommitted)..., 9.5,9.9
我想编写一个查询,返回data
中唯一Table 2
的{{1}},其最大日期为Table 1
,如上表所示:
id2 date number
2 2015-01-10 1.0
2 2015-01-10 1.1
2 2015-01-10 1.2
2 2015-01-10 1.3
...
2 2015-01-10 9.5
2 2015-01-10 9.9
10 2015-02-11 ***
10 2015-02-11 ***
...
10 2015-02-11 ***
每个唯一id2
在查询输出中显示N
次。
我能够根据模糊的答案得到唯一的id2
,如下所示:
select * from (
select
t2.id2, t1.date, t2.data,
row_number() over (partition by t2.data order by t1.date desc) rn
from table1 t1
join table2 t2 on t1.id2 = t2.id2
) t where rn = 1;
但我不知道如何从那里继续。非常感谢。
答案 0 :(得分:0)
您可以使用管道功能:</ p>
CREATE or replace TYPE test_type AS TABLE OF varchar2(40)
CREATE or replace FUNCTION test_func (d VARCHAR2)
RETURN test_type
PIPELINED
IS
BEGIN
FOR C1 IN ( SELECT REGEXP_SUBSTR (d, '[^,]+', 1, LEVEL) x
FROM DUAL
CONNECT BY REGEXP_SUBSTR (d, '[^,]+', 1, LEVEL) IS NOT NULL)
LOOP
PIPE ROW (c1.x);
END LOOP;
END;
/
WITH test
AS ( your_query_here )
SELECT x.id2, x.mydate, y.*
FROM test x, TABLE (test_func (x.d)) y
我在这里使用mydate而不是date(保留字)和d而不是数据。样品:
WITH test
AS (SELECT 2 AS id2, SYSDATE AS mydate, '1.0,1.1,1.2,11,1.4,1.5,2.6,2.7,2.8,2.9,44,55' AS d FROM DUAL
UNION ALL
SELECT 3 AS id2, SYSDATE + 1 AS mydate, '19.5,19.9,11.5,11.1,21.2,33,1.4,1.5,2.6,2.7,2.8,2.9' AS d
FROM DUAL
UNION ALL
SELECT 4 AS id2, SYSDATE + 1 AS mydate, '9.5,9.9,1.5,1.1,1.2,66,1.4,1.5,2.6,2.7,2.8,2.9' AS d
FROM DUAL)
SELECT x.id2, x.mydate, y.*
FROM test x, TABLE (test_func (x.d)) y
一些链接:
How to split comma separated string and pass to IN clause of select statement
答案 1 :(得分:0)
就像其他人所说的那样,如果桌子设计得当,你就不必这样做了。如果这是一个经常使用的对象,那么最好解决实际问题。但是,如果这只是一次性的事情,您可以使用递归查询。这在Teradata中有效,Oracle可能有类似的模拟。
WITH RECURSIVE processDelimited(ID2,dataVarchar2,parsedElement,indexElement) AS (
SELECT
ID2
,dataVarchar2
,strtok(dataVarchar2,',',1)
,0
FROM tableWithDelimitedColumns
UNION ALL
SELECT
ID2
,dataVarchar2
,strtok(dataVarchar2,',',indexElement + 1)
,indexElement + 1
FROM processDelimited
WHERE indexElement < 120
)
SELECT
processDelimited.ID2
,parsedElement
,indexElement
FROM processDelimited
INNER JOIN (
SELECT
ID2
,DATE_COL
FROM table1
QUALIFY row_number() OVER(PARTITION BY ID2 ORDER BY DATE_COL DESC) = 1) AS id2MaxDate
ON processDelimited.ID2 = id2MaxDate.ID2
WHERE parsedElement IS NOT NULL
ORDER BY processDelimited.ID2
基本上你只是从空字符串开始并循环追加行。
使用的TD函数只是从分隔字段中提取索引。实施例
strtok('1,2,3,4,5',',',2) = 2
当然,这在计算上非常昂贵,因此对于大型桌子来说并不是很好。