[英]Teradata SQL- Split a string and search for that combination in respective fields
[英]Teradata string/text search
我在teradata中有2個表。 表A和表B
表A有2列,如下所示
表A
第 1 列 --> 數據庫名稱
第 2 列 --> 表名
TableB 有多個列,包括一個文本列。
我想從表 B 的文本列中的表 A 中搜索 databasename.tablename。 不能使用 like 運算符,因為表 A 中大約有 2000 個不同的表名。我嘗試使用位置連接來執行此操作,如下所示,但查詢運行時間非常長,PJI 高,我不得不手動中止它
select distinct a.Tablename ,b.text
from TableA a
inner join TableB b
on position(Trim(b.Text) in Trim('a.Databasename.'||a.tablename))>0
where b.theDate between add_months(date,-6) and date
UNION ALL
select distinct a.Tablename ,b.text
from TableA a
inner join TableB b
on position (Trim('a.Databasename.'||a.tablename) in Trim(b.Text)) >0
where b.theDate between add_months(date,-6) and date;
是否有其他方法可以進行上述字符串搜索。 請分享SQL。
謝謝
REGEXP_SIMILAR:
一種選擇是使用REGEXP_SIMILAR()
,它比LIKE
更精確。 我不確定是否會更快,但值得一試:
CREATE MULTISET VOLATILE TABLE TABLEA
(databasename varchar(30), tablename varchar(30))
PRIMARY INDEX (databasename, tablename) ON COMMIT PRESERVE ROWS;
INSERT INTO TABLEA VALUES ('dba','tbla');
INSERT INTO TABLEA VALUES ('dba','tblb');
INSERT INTO TABLEA VALUES ('dbb','tbla');
CREATE MULTISET VOLATILE TABLE TABLEB
(id int, sqlqry VARCHAR(5000))
ON COMMIT PRESERVE ROWS;
INSERT INTO TABLEB VALUES (1, 'SELECT * FROM dba.tbla;');
INSERT INTO TABLEB VALUES (2, 'SELECT smoecolumn FROM dba.tblb INNER JOIN dba.tbla ON foo = bar WHERe 1=1;');
INSERT INTO TABLEB VALUES (3, 'SELECT * FROM dbb.tbla WHERE foo=bar');
SELECT *
FROM TABLEA
INNER JOIN TABLEB
ON REGEXP_SIMILAR(TABLEB.sqlqry, '^.*' || TABLEA.databasename || '\.' || TABLEA.tablename || '.*$', 'i') = 1;
+-----+------+---+-----------------------------------------------------------------------------+
| dbb | tbla | 3 | SELECT * FROM dbb.tbla WHERE foo=bar |
| dba | tbla | 2 | SELECT smoecolumn FROM dba.tblb INNER JOIN dba.tbla ON foo = bar WHERe 1=1; |
| dba | tbla | 1 | SELECT * FROM dba.tbla; |
| dba | tblb | 2 | SELECT smoecolumn FROM dba.tblb INNER JOIN dba.tbla ON foo = bar WHERe 1=1; |
+-----+------+---+-----------------------------------------------------------------------------+
STRTOK_SPLIT_TO_TABLE:
這就是我用strtok_split_to_tables
評論瞄准的地方。 基本上,您將TABLEB
的 sql TABLEB
為單詞(按空格和;
字符拆分)。 這將為每個單詞生成一行。
從該列表中,您只需保留包含句點的單詞(例如databasename.tablename
)。
然后你可以在 TABLEB 和 TABLEA 之間進行連接:
CREATE MULTISET VOLATILE TABLE TABLEA
(databasename varchar(30), tablename varchar(30))
PRIMARY INDEX (databasename, tablename) ON COMMIT PRESERVE ROWS;
INSERT INTO TABLEA VALUES ('dba','tbla');
INSERT INTO TABLEA VALUES ('dba','tblb');
INSERT INTO TABLEA VALUES ('dbb','tbla');
CREATE MULTISET VOLATILE TABLE TABLEB
(id int, sqlqry VARCHAR(5000))
ON COMMIT PRESERVE ROWS;
INSERT INTO TABLEB VALUES (1, 'SELECT * FROM dba.tbla;');
INSERT INTO TABLEB VALUES (2, 'SELECT smoecolumn FROM dba.tblb INNER JOIN dba.tbla ON foo = bar WHERe 1=1;');
INSERT INTO TABLEB VALUES (3, 'SELECT * FROM dbb.tbla WHERE foo=bar');
WITH sqlwords AS
(
SELECT tablebid, sqlwordnum, sqlword
FROM TABLE (strtok_split_to_table(TABLEB.id, TABLEB.sqlqry, ' ;')
RETURNS (tablebid integer, sqlwordnum integer, sqlword varchar(100)character set unicode) ) as sqlwordsplitter
WHERE sqlwordsplitter.sqlword like '%.%'
)
SELECT TABLEA.*, TABLEB.*
FROM TABLEA
INNER JOIN sqlwords
ON TABLEA.databasename = strtok(sqlwords.sqlword, '.', 1)
AND TABLEA.tablename = strtok(sqlwords.sqlword, '.', 2)
INNER JOIN TABLEB
ON sqlwords.tablebid = TABLEB.id;
+-----+------+---+-----------------------------------------------------------------------------+
| dbb | tbla | 3 | SELECT * FROM dbb.tbla WHERE foo=bar |
| dba | tbla | 2 | SELECT smoecolumn FROM dba.tblb INNER JOIN dba.tbla ON foo = bar WHERe 1=1; |
| dba | tbla | 1 | SELECT * FROM dba.tbla; |
| dba | tblb | 2 | SELECT smoecolumn FROM dba.tblb INNER JOIN dba.tbla ON foo = bar WHERe 1=1; |
+-----+------+---+-----------------------------------------------------------------------------+
這不會很快,因為我們必須進行分詞,但它肯定會完成工作。
如果是為了從 CREATE TABLE AS 中提取單個表名,您可以對表/數據庫名應用正則表達式:
RegExp_Substr(SqlTextInfo, 'AS\s+?(.*?[.])?\K.+?\s+?(?=WITH\s)',1,1,'i') AS TableName
RegExp_Substr(SqlTextInfo, 'AS\s+?\K.*?(?=[.](.+?\s+)?WITH\s)',1,1,'i') AS DatabaseName
如果缺少數據庫名稱,您可以 COALESCE QryLogV.DefaultDatabase
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.