以下是我的数据集
Year Month Holiday list
----------------------------------------------------------
2007 1 WWHHWWWWWHHWWWWWHHWWWWWHHWWWWWH
2008 4 HWWWWWHHWWWWWHHWWWWWHHWWWWWHHWW
我想编写SQL查询以获得低于输出,其中显示每个“H”的位置。
Year Month Holiday list
-----------------------------------------------------
2007 1 3 4 10 11 18 19 25 26 31
2008 4 1 7 8 14 15 21 22 28 29
Oracle中的INSTR
函数返回第一个字符的位置。所以,我不能用它。
我可以编写一个Function并将Holiday List列值传递给它。循环通过字符串和 找到每个“H”的位置。但是,我想通过纯SQL选择查询来实现这一点。
如何通过Oracle数据库中的SQL查询找到字符串中相同字符的每个位置?
答案 0 :(得分:4)
这样的事可能会这样做。您可以使用INSTR
函数和分层查询来遍历字符串,然后使用LISTAGG
分析函数来连接结果。
WITH data AS (
SELECT 2007 year, 1 month, 'WWHHWWWWWHHWWWWWHHWWWWWHHWWWWWH' holiday_list FROM DUAL
UNION
SELECT 2008 year, 4 month, 'HWWWWWHHWWWWWHHWWWWWHHWWWWWHHWW' holiday_list FROM DUAL)
SELECT year, month, (SELECT LISTAGG(INSTR(holiday_list,'H',1,LEVEL),' ') WITHIN GROUP (ORDER BY LEVEL)
FROM DUAL
CONNECT BY LEVEL < INSTR(holiday_list,'H',1,LEVEL)) S
FROM data;
答案 1 :(得分:0)
您可以获得一个列表,请参阅dbfiddle This is what Composer download,every time I install the extension
SELECT id, INSTR(some, 'H', 1, c.no) AS Pos
FROM tst CROSS JOIN consecutive c
WHERE INSTR(some, 'H', 1, c.no) > 0
这会为您提供一个带有H的日期列表。然后您可以尝试转置此列表。但是请注意,那里有一个故意的CROSS JOIN,因此对于数据中的每一行,您将使用此语句获得最多31行。就像Tim Biegeleisen所说的那样,为此使用UDF可能更好。