在同一个表中,我有两列,每列都有一个以下格式的字符串:
| column1 | column2
--------------------------------|---------------------------------
| Soda: 10, Watter:5, Juice: 12 | Soda: 7, Watter:20, Juice: 15 |
如何创建一个查询,只提取第1列和第2列之间Water值不同的行?
您的列非常接近JSON。如果您使用的是Oracle12c及以上版本,请考虑将它们存储为JSON。请参阅Oracle中的JSON。但是,我仍然想说,除非绝对有必要以这种方式存储,否则最好通过规范化来重新设计表格。
如果您确实在使用12c+,那么也可以使用JSON_VALUE
将它们转换为JSON,以获得单独的元素进行比较。
SELECT *
FROM (
SELECT '{' || column1 || '}' AS column1,
'{' || column2 || '}' AS column2
FROM t
)
WHERE
JSON_VALUE(column1,'$.Watter' ) <> JSON_VALUE(column2,'$.Watter' );
我没有添加额外的验证。如果属性Watter
在某些情况下不存在,则必须使用COALESCE
或NVL
处理NULL
。
LiveSQL演示(执行时需要免费OTN帐户(
select substr(col1,instr(col1,'Watter:')+7,instr(col1,', Juice:')-instr(col1,', Watter:')-9) as from_col1
,substr(col2,instr(col2,'Watter:')+7,instr(col2,', Juice:')-instr(col2,', Watter:')-9) as from_col2
,col1
,col2
from t
where substr(col1,instr(col1,'Watter:')+7,instr(col1,', Juice:')-instr(col1,', Watter:')-9)
<> substr(col2,instr(col2,'Watter:')+7,instr(col2,', Juice:')-instr(col2,', Watter:')-9)
试试这个方法:
-- CREATE SAMPLE TABLE
;with strings as
(
SELECT 'Soda: 1, Watter:5, Juice: 4' AS Col1, 'Soda: 5, Watter:5, Juice: 12' AS Col2 UNION ALL
SELECT 'Soda: 2, Watter:1, Juice: 5', 'Soda: 7, Watter:2, Juice: 9' UNION ALL
SELECT 'Soda: 3, Watter:6, Juice: 6', 'Soda: 8, Watter:7, Juice: 10'
)
-- YOUR QUERY
SELECT *
FROM strings
WHERE SUBSTRING(Col1,CHARINDEX('Watter:',Col1)+7,CAST(CHARINDEX(', Juice',Col1) AS int)-CAST(CHARINDEX('Watter:',Col1)+7 AS int))
<> SUBSTRING(Col2,CHARINDEX('Watter:',Col2)+7,CAST(CHARINDEX(', Juice',Col2) AS int)-CAST(CHARINDEX('Watter:',Col2)+7 AS int))