Запрос на шаблон * ** ***

#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'));
 

DBFiddle