#sql #oracle
Вопрос:
У меня возник вопрос в интервью, который мне нужно распечатать ниже, используя шаблон SQL. SQL не должен иметь двойного решения.
*
* *
* * *
Я дал ответ, как показано ниже:
select lpad(' ',level,'*') from dual
connect by level <=3;
Еще один вопрос был с той же концепцией-напечатать мое имя вертикально, как показано ниже.
M
A
N
A
S
I
Любое предложение, как мы можем напечатать их без двойных.
Комментарии:
1. Этот вопрос не имеет допустимого ответа и может привести к решениям, основанным на мнениях: системные таблицы,
odci...list
конструктор,json_table
,xmltable
, хранимая процедура с циклом, таблица, созданная вручную, что угодно2. Я не верю, что этот вопрос основан на мнении. Существует много правильных ответов. ОП не просит лучшего решения, просто решение. Как уже говорилось, это был вопрос для интервью, и интервьюеры обычно прибегают к хитростям (например, не используйте
DUAL
в данном случае), чтобы посмотреть, какие творческие решения вы можете придумать. Если бы вы искали оптимальное решение, то оно, скорее всего, основывалось бы на мнении, и у вас не было бы ограничений в том, что вы не сможете его использоватьDUAL
. Все приведенные ниже ответы являются действительными, поскольку они приводят к данным, которые ищет OP.
Ответ №1:
Один из вариантов замены DUAL
-просто выбрать из любой таблицы/представления, содержащей хотя бы одну строку, и выбрать WHERE ROWNUM = 1
. В приведенном ниже запросе я использую ALL_OBJECTS
представление.
SELECT LPAD ('*', LEVEL, '*')
FROM (SELECT 1
FROM all_objects
WHERE ROWNUM = 1)
CONNECT BY LEVEL <= 3;
LPAD('*',LEVEL,'*')
______________________
*
**
***
Для второй проблемы вы можете использовать аналогичное решение об использовании любой таблицы/представления по крайней мере с одной строкой и выбрать из нее. Еще одно дерзкое решение-использовать a SYS.ODCIVARCHAR2LIST
, чтобы просто написать свое имя. Оба приведенных ниже запроса дадут вам один и тот же результат.
--Query 1
SELECT SUBSTR (your_name, LEVEL, 1) AS letters
FROM (SELECT 'MANASI' AS your_name
FROM all_objects
WHERE ROWNUM = 1)
CONNECT BY LEVEL <= LENGTH (your_name);
--Query 2 (Cheeky solution)
SELECT COLUMN_VALUE AS letters
FROM TABLE (sys.odcivarchar2list ('M',
'A',
'N',
'A',
'S',
'I'));
--Result of both queries
LETTERS
__________
M
A
N
A
S
I
Ответ №2:
Просто используйте любую другую таблицу и ограничьте ее одной строкой:
WITH rsqfc ( value ) AS (
SELECT '*' FROM all_tables WHERE ROWNUM = 1
UNION ALL
SELECT value || ' *'
FROM rsqfc
WHERE LENGTH(value) <= 5
)
SELECT value
FROM rsqfc;
Или:
SELECT '*' AS value FROM all_tables WHERE ROWNUM = 1
UNION ALL
SELECT * FROM (SELECT '* *' FROM all_objects FETCH FIRST ROW ONLY)
UNION ALL
SELECT '* * *' FROM (
SELECT ROW_NUMBER() OVER (ORDER BY ROWNUM) AS rn FROM all_tab_columns
)
WHERE rn = 1;
или ограничьте его количеством строк, которое вы хотите:
SELECT SUBSTR('* * *', 1, 2 * ROWNUM - 1) AS value
FROM all_tables
WHERE ROWNUM <= 3;
Все выходные данные:
ценность * * * * * *
бд<>скрипка <>здесь
Ответ №3:
Интересно, что первый из них похож на вопрос о кодовом гольфе, на который я ответил (Ссылка)
Единственное, что я могу придумать, — это выбрать из системного представления вместо двойного.
SELECT LPAD('*', ROWNUM, '*')
FROM all_objects ao
WHERE ROWNUM <= 3;
Для второго:
SELECT SUBSTR('MANASI', ROWNUM, 1)
FROM all_objects ao
WHERE ROWNUM <= LENGTH('MANASI');
Ответ №4:
Вы можете использовать выражение XQuery в xmltable()
качестве генератора строк:
select rpad('*',rownum,'*')
from xmltable('1 to 3');
select substr('MANASI',rownum,1)
from xmltable('1 to 5'));