有谁可以请缩短这个查询?

时间:2014-06-04 11:52:12

标签: mysql sql

enter image description here此查询为现有架构生成下一个数据文件名。 对于例如id last数据文件名是test_schema_05.dbf 那么这个查询给出了test_schema_06.dbf 我需要缩短这个查询。

这可能吗?

SELECT  CONCAT
    (SUBSTR
        (MAX
            (SUBSTR 
                (file_name,
                INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
                )
            ),
            1,
            INSTR 
                (MAX 
                    (SUBSTR 
                        (file_name, 
                        INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
                        )
                    ),
                    '_',
                    1,
                    (LENGTH 
                        (MAX 
                            (SUBSTR 
                                (file_name, 
                                INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
                                )
                            )
                        ) - LENGTH
                            (REPLACE
                                (MAX
                                    (SUBSTR
                                        (file_name, 
                                        INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
                                        )
                                    ),
                                    '_'
                                )
                            )
                    )
                )
        ),
        CONCAT
            ('0', 
            SUBSTR
                (MAX 
                    (SUBSTR 
                        (file_name, 
                        INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/' ))) + 1
                        )
                    ),
                    INSTR
                        (MAX 
                            (SUBSTR 
                                (file_name,
                                INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/' ))) + 1
                                )
                            ),
                            '_',
                            1,
                            (LENGTH
                                (MAX
                                    (SUBSTR
                                        (file_name,
                                        INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
                                        )
                                    )
                                ) - LENGTH
                                    (REPLACE
                                        (MAX
                                            (SUBSTR
                                                (file_name,
                                                INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
                                                )
                                            ),
                                            '_'
                                        )
                                    )
                            )
                        ) + 1,
                        INSTR 
                            (MAX 
                                (SUBSTR 
                                    (file_name,
                                    INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1
                                    )
                                ),
                                '.',
                                1
                            ) - INSTR
                                (MAX 
                                    (SUBSTR 
                                        (file_name, 
                                        INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/' ))) + 1
                                        )
                                    ),
                                    '_',
                                    1,
                                    (LENGTH
                                        (MAX
                                            (SUBSTR
                                                (file_name,
                                                INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/' ))) + 1
                                                )
                                            )
                                        ) - LENGTH
                                            (REPLACE
                                                (MAX
                                                    (SUBSTR
                                                        (file_name,
                                                        INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/' ))) + 1
                                                        )
                                                    ),
                                                    '_'
                                                )
                                            )
                                    )
                                ) - 1
                ) + 1
            )
    )

|| '.dbf'   AS  data_file_name
FROM    dba_data_files
WHERE   tablespace_name = 
    (SELECT     default_tablespace
    FROM        dba_users
    WHERE       username = 'schema_name'
    );

2 个答案:

答案 0 :(得分:0)

这几乎让我哭了。此外,您的查询看起来有些错误,因为您的MAX函数似乎只包含一个值,即一个字符串

你有很多重复的行阻塞你的查询,当你试图阅读它时你的大脑。将其提取到变量!假设这一切都在某个地方的sproc中,你最终得到这样的东西:

DECLARE i_intLocation   INTEGER;
SET i_intLocation = INSTR (file_name, '/', 1, LENGTH (file_name) - LENGTH (REPLACE (file_name, '/'))) + 1;

DECLARE i_strSubstr     VARCHAR;
SET i_strSubstr = (SUBSTR (file_name, i_intLocation));

SELECT  
CONCAT(
    SUBSTR(
        MAX(i_strSubstr),
        1,
        INSTR(
            MAX(i_strSubstr),
            '_',
            1,
            (
                LENGTH(MAX(i_strSubstr)) 
                - LENGTH(
                    REPLACE(
                        MAX(i_strSubstr),
                        '_'
                    )
                )
            )
        )
    ),
    CONCAT(
        '0', 
        SUBSTR(
            MAX(i_strSubstr),
            INSTR(
                MAX(i_strSubstr),
                '_',
                1,
                (
                    LENGTH(MAX(i_strSubstr))
                    - LENGTH(
                        REPLACE(
                            MAX(i_strSubstr),
                            '_'
                        )
                    )
                )
            ) + 1,
            INSTR(
                MAX(i_strSubstr),
                '.',
                1
            ) 
            - INSTR(
                MAX(i_strSubstr),
                '_',
                1,
                (
                    LENGTH(MAX(i_strSubstr))
                    - LENGTH(
                        REPLACE(
                            MAX(i_strSubstr),
                            '_'
                        )
                    )
                )
            ) - 1
        ) + 1
    )
)

|| '.dbf'   AS  data_file_name
FROM    dba_data_files
WHERE   tablespace_name = 
    (SELECT     default_tablespace
    FROM        dba_users
    WHERE       username = 'schema_name'
    );

答案 1 :(得分:0)

使用子查询来获取最高的文件名以缩短代码,它会出现类似的情况,但我怀疑这不再有效(并且可能效率较低)。

SELECT    CONCAT(SUBSTR(sub1.derived_bit,1,INSTR(sub1.derived_bit,'_',1,(LENGTH(sub1.derived_bit)- LENGTH(REPLACE(sub1.derived_bit,'_'))))),
CONCAT('0',SUBSTR(sub1.derived_bit,INSTR(sub1.derived_bit,'_',1,(LENGTH(sub1.derived_bit)- LENGTH(REPLACE(sub1.derived_bit,'_'))))+ 1,INSTR
(sub1.derived_bit,'.',1)- INSTR(sub1.derived_bit,'_',1,(LENGTH(sub1.derived_bit)- LENGTH(REPLACE(sub1.derived_bit, '_' ))))- 1)+ 1), '.dbf') AS data_file_name
FROM 
(
    SELECT MAX(SUBSTR(file_name, INSTR(file_name, '/', 1, LENGTH(file_name) - LENGTH(REPLACE(file_name, '/'))) + 1)) as derived_bit
    FROM dba_data_files 
    INNER JOIN dba_users
    ON dba_data_files.tablespace_name = dba_users.default_tablespace AND username = 'schema_name'
) sub1

然而,这只是基于你的代码有语法错误(我在上面的代码中重复了)。例如,您的代码使用带有4个参数的INSTR(应该只有2个)。类似地,您只使用2个参数的REPLACE。您的函数正在寻找'/',而您提供的文件名作为示例不包含任何'/'字符。

文件名的格式有多固定?是否只有1。在文件名中?是否会在.dbf之前立即增加数字?