通过SQL查询在字符串中查找相同字符的每个位置

时间:2017-11-24 06:44:19

标签: sql oracle

以下是我的数据集

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查询找到字符串中相同字符的每个位置?

2 个答案:

答案 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可能更好。