powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите, пожалуйста, решить задачу
19 сообщений из 19, страница 1 из 1
Помогите, пожалуйста, решить задачу
    #39911347
thtrx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Для всех таблиц схемы вывести:
1) Имя таблицы;
2) Имя первого (по алфавиту) неуникального индекса;
3) Количество столбцов первого неуникального индекса;
4) Имя первого по алфавиту столбца первого неуникального индекса.
5) Имя первого (по алфавиту) уникального индекса;
6) Количество столбцов первого уникального индекса;
7) Имя второго по алфавиту столбца второго по алфавиту уникального индекса;
8) Общее число неуникальных индексов;
9) Общее число уникальных индексов;


Особенно 4 и 7 пункты проблемы вызывают
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39911352
Synoptic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
thtrx, мы готовы помочь вам в сложных моментах.
Выкладывайте своё решение и ваши вопросы относительно непонятных моментов.
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39911353
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
thtrx
4 и 7 пункты проблемы вызывают
first/last
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39911369
thtrx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Synoptic,
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
WITH min_index AS /* первый по алфавиту уникальный и неуникальный индексы в таблице */
(
	SELECT table_name, MIN(index_name) index_name, uniqueness, COUNT(DISTINCT index_name) cnt
	FROM user_indexes
	GROUP BY table_name, uniqueness
),
ind_col_count AS /* число столбцов в каждом индексе */
(
	SELECT index_name, COUNT(column_name) cnt
	FROM user_ind_columns
	GROUP BY index_name
),
 full_ind AS /* первый уникальный и неуникальный индексы в таблице */
(
	SELECT table_name, index_name, uniqueness, COUNT(DISTINCT index_name) cnt
	FROM user_indexes
	GROUP BY table_name, uniqueness
),
second_index AS -- TODO: второй по алфавиту уникальный индекс
(
	SELECT table_name, index_name index_name, uniqueness, COUNT(DISTINCT index_name) cnt
	FROM user_indexes
    WHERE uniqueness = 'UNIQUE'
	GROUP BY table_name, uniqueness
    ORDER BY index_name
)

SELECT 
	CASE WHEN ui.table_name IS NULL 
		THEN nui.table_name 
		ELSE ui.table_name END	table_name	, -- имя таблицы с индексами
	NVL(nui.index_name, '-') 	nui1_name	, -- первый неуникальный индекс 
    NVL(nui_cnt.cnt, 0) 		nui1_col_cnt, -- число столбцов в нем
	NVL(ui.index_name, '-') 	ui1_name	, -- первый   уникальный индекс
    NVL(ui_cnt.cnt, 0) 	  		ui1_col_cnt , -- число столбцов в нем
	NVL(nui.cnt, 0) 			nui_cnt		, -- число неуникальных индексов
	NVL(ui.cnt, 0) 				ui_cnt		, -- число уникальных индексов
    NVL(col_21.column_name, '-') nui_cons1_col1,-- имя первого столбца первого неуникального индекса
	NVL(col_22.column_name, '-') uil_cons2_col2 -- имя второго столбца второго уникального индекса
    
FROM 	  min_index nui 		-- первый неуникальный индекс таблицы 
FULL JOIN min_index ui  		-- первый   уникальный индекс таблицы 
	ON  nui.table_name = ui.table_name 
    AND nui.uniqueness = 'NONUNIQUE'
	AND  ui.uniqueness = 'UNIQUE'
LEFT JOIN ind_col_count nui_cnt -- число слолбцов неуникального индекса
	ON nui_cnt.index_name = nui.index_name
LEFT JOIN ind_col_count ui_cnt  -- число столбцов   уникального индекса
	ON  ui_cnt.index_name =  ui.index_name
LEFT JOIN user_ind_columns col_21
	ON col_21.index_name = nui.index_name
	AND col_21.COLUMN_POSITION = 1 -- имя первого столбца первого неуникального индекса
LEFT JOIN user_ind_columns col_22
	ON col_22.index_name = ui.index_name -- TODO: найти имя второго уникального индекса
	AND col_22.COLUMN_POSITION = 2 -- имя второго столбца второго уникального индекса
WHERE 
	   nui.uniqueness = 'NONUNIQUE' AND nui.uniqueness IS NOT NULL 
	OR  ui.uniqueness = 'UNIQUE' 	AND  ui.uniqueness IS NOT NULL
ORDER BY ui.table_name;



Не могу сообразить как найти второй по алфавиту индекс. И, видимо, надо еще отсортировать по алфавиту имена столбцов и выбирать оттуда.
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39911416
iOracleDev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
thtrx,

Analytic Functions , row_number, count, при агрегации case when (...).
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912174
thtrx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iOracleDev, аналитические функции использовать нельзя. Остальное написано слишком абстрактно. Можно по подробнее, пожалуйста.
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912177
iOracleDev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
thtrx
iOracleDev, аналитические функции использовать нельзя.

Почему задачу на аналитические функции нельзя решать с помощью аналитических функций?
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912185
thtrx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iOracleDev, ну вот так... преподаватель не разрешает...
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912189
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
thtrx
преподаватель не разрешает...
А на форумы бегать разрешает?
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912191
thtrx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic, ничего не поделаешь
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912195
Maxim Demenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
thtrx,

В ваших примерах (сильно не вникал ибо глаз режет) подзапросы как минимум
1) синтактически неверны ( select list doesn't match group by list )
2) бессмысленны (все индексы в схеме находятся в одном namespace, поэтому дубликатов имен быть не может , соответственно, нафиг их считать)


Как аналитику (извращенно ) можно заменить агрегацией - пример вот.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
-- alter session set nls_sort='binary'
  SELECT table_name,
         index_name,
         uniqueness,
         (select count(*)
            from user_indexes i
           where i.index_name <= o.index_name
             and uniqueness = 'UNIQUE')
    FROM user_indexes o
   WHERE uniqueness = 'UNIQUE'
   ORDER BY index_name



Regards
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912208
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iOracleDev
thtrx,

Analytic Functions , row_number, count, при агрегации case when (...).


Нуи с какого перепугу тут аналитика когда результат 1 строка на таблицу - типичная агрегация

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
WITH X AS (
           SELECT  T.TABLE_NAME,
                   I.UNIQUENESS,
                   IC.INDEX_OWNER,
                   IC.INDEX_NAME,
                   IC.COLUMN_NAME
             FROM  USER_TABLES T,
                   ALL_INDEXES I,
                   ALL_IND_COLUMNS IC
             WHERE I.TABLE_OWNER(+) = SYS_CONTEXT('USERENV','CURRENT_USER')
               AND I.TABLE_NAME(+) = T.TABLE_NAME
               AND IC.INDEX_OWNER(+) = I.OWNER
               AND IC.INDEX_NAME(+) = I.INDEX_NAME
          )
SELECT  TABLE_NAME,
        MIN(
            CASE UNIQUENESS
              WHEN 'NONUNIQUE' THEN INDEX_NAME
            END
           )
          KEEP(
               DENSE_RANK FIRST
               ORDER BY CASE UNIQUENESS
                          WHEN 'NONUNIQUE' THEN 1
                          ELSE 2
                        END,
                        INDEX_OWNER
              ) FIRST_NONUNIQUE_INDEX_NAME,
        COUNT(
              CASE UNIQUENESS
                WHEN 'NONUNIQUE' THEN 1
              END
             )
          KEEP(
               DENSE_RANK FIRST
               ORDER BY CASE UNIQUENESS
                          WHEN 'NONUNIQUE' THEN 1
                          ELSE 2
                        END,
                        INDEX_NAME,
                        INDEX_OWNER
              ) FIRST_NONUNIQUE_INDEX_COL_CNT,
        MIN(
            CASE UNIQUENESS
              WHEN 'NONUNIQUE' THEN COLUMN_NAME
            END
           )
          KEEP(
               DENSE_RANK FIRST
               ORDER BY CASE UNIQUENESS
                          WHEN 'NONUNIQUE' THEN 1
                          ELSE 2
                        END,
                        INDEX_NAME,
                        INDEX_OWNER
              ) FIRST_NONUNIQUE_INDEX_FRST_COL
  FROM  X
  GROUP BY TABLE_NAME
  ORDER BY TABLE_NAME
/



Остальное TC сам дорисует (если осилит).

SY.
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912212
thtrx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Demenko, к сожалению, коррелированные подзапросы тоже нельзя использовать


в итоге сделал так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
SELECT
    t1.table_name, -- имя таблицы
    nvl(t2.nui1_name, '-') AS f_nui_name, -- первый неуникальный индекс по алфавиту
    nvl(t3.nui1_col_cnt, 0) AS f_nui_col_cnt, -- число столбцов в нем
    nvl(column_name, '-') AS f_col_f_nui, -- имя первого по алфавиту столбца первого по алфавиту неуникального индекса
    nvl(t4.ui1_name, '-') AS f_ui_name, -- первый уникальный индекс по алфавиту
    nvl(t5.ui1_col_cnt, 0) AS f_ui_col_cnt, -- число столбцов в нем
    nvl(min_name_ui2_col2, '-') AS s_col_f_ui, -- имя второго по алфавиту столбца второго по алфавиту уникального индекса
    nvl(t2.nui_cnt, 0) AS nui_cnt, -- число неуникальных индексов
    nvl(t4.ui_cnt, 0) AS ui_cnt -- число уникальных индексов
FROM
    (
        SELECT DISTINCT
            table_name
        FROM
            user_indexes
    ) t1 -- получение имен таблиц, имеющих индексы
    LEFT JOIN (
        SELECT
            table_name,
            MIN(index_name) AS nui1_name,
            COUNT(index_name) AS nui_cnt
        FROM
            user_indexes
        WHERE
            uniqueness = 'NONUNIQUE'
        GROUP BY
            table_name
    ) t2 -- получение имен первых по алфавиту неуникальных индексов и количество их столбцов
     ON t1.table_name = t2.table_name
    LEFT JOIN (
        SELECT
            index_name,
            MIN(column_name) AS column_name
        FROM
            user_ind_columns
        GROUP BY
            index_name
    ) g1 ON t2.nui1_name = g1.index_name -- получение имени первого столбца первого неуникального индекса
    LEFT JOIN (
        SELECT
            table_name,
            COUNT(index_name) AS nui1_col_cnt,
            MIN(index_name),
            index_name
        FROM
            user_ind_columns
        GROUP BY
            index_name,
            table_name
    ) t3 -- получение количества столбцов первого неуникального индекса
     ON t3.index_name = t2.nui1_name
    LEFT JOIN (
        SELECT
            table_name,
            MIN(index_name) AS ui1_name,
            COUNT(index_name) AS ui_cnt
        FROM
            user_indexes
        WHERE
            uniqueness = 'UNIQUE'
        GROUP BY
            table_name
    ) t4 -- получение имен первых по алфавиту уникальных индексов и количество их столбцов
     ON t4.table_name = t1.table_name
    LEFT JOIN (
        SELECT
            table_name,
            COUNT(index_name) AS ui1_col_cnt,
            MIN(index_name),
            index_name
        FROM
            user_ind_columns
        GROUP BY
            index_name,
            table_name
    ) t5 -- получение количества столбцов первого уникального индекса
     ON t5.index_name = t4.ui1_name
-----------
    LEFT JOIN (
        SELECT
            table_name,
            min_name_ui2_col2
        FROM
            (
                SELECT
                    table_name,
                    MIN(index_name) AS ui2_name
                FROM
                    (
                        SELECT
                            table_name,
                            index_name
                        FROM
                            user_indexes
                        WHERE
                            uniqueness = 'UNIQUE'
                        MINUS
                        SELECT
                            table_name,
                            MIN(index_name) AS index_name
                        FROM
                            user_indexes
                        WHERE
                            uniqueness = 'UNIQUE'
                        GROUP BY
                            table_name
                    )
                GROUP BY
                    table_name
            ) g2 -- получение второго по алфавиту имени уникального индекса
            LEFT JOIN (
                SELECT
                    index_name,
                    MIN(column_name) AS min_name_ui2_col2
                FROM
                    (
                        SELECT
                            index_name,
                            column_name
                        FROM
                            user_ind_columns
                        MINUS
                        SELECT
                            index_name,
                            MIN(column_name) AS column_name
                        FROM
                            user_ind_columns
                        GROUP BY
                            index_name
                    )
                GROUP BY
                    index_name
            ) g3 ON g2.ui2_name = g3.index_name -- получение второго по алфавиту имени столбца второго по алфавиту уникального индекса
    ) g2 ON t1.table_name = g2.table_name
ORDER BY
    t1.table_name;



вроде работает

но если есть идеи как решить пункт 7 по другому или вы нашли ошибку, обязательно напишите
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912222
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
thtrx,

В общем случае индекс на твою таблицу может принадлежать другому юзеру и посему USER_INDEXES не даст всю картину.

SY.
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912234
iOracleDev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
типичная агрегация

Как получить не первую или последнюю, а произвольную n-ю по некоторому порядку строку в результате агрегации?
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912241
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iOracleDev

Как получить не первую или последнюю, а произвольную n-ю по некоторому порядку строку в результате агрегации?


Упс, упустил "7) Имя второго по алфавиту столбца второго по алфавиту уникального индекса;"

SY.
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912274
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
iOracleDev

Как получить не первую или последнюю, а произвольную n-ю по некоторому порядку строку в результате агрегации?
Упс, упустил "7) Имя второго по алфавиту столбца второго по алфавиту уникального индекса;"
Агрегацию не отменяет. Пример документации по агрегатам реализует функцию secondmax, несложно переделать на secondmin. Для небольших объемов вполне сойдет json_arrayagg/$[1].
В принципе, для развлечения есть множество способов: collect, listagg, model, match_recognize... но стоит ли метать бисер перед "преподавателем", который ожидает скалярный подзапрос.
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912440
iOracleDev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
thtrx
коррелированные подзапросы тоже нельзя использовать

В таком виде тоже нельзя?
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
select t.table_name
     , a.index_name
     , a.uniqueness
     , col2.column_name
     , i2.index_name
from all_tables t
     left join all_indexes a on t.owner = a.table_owner and
                                t.table_name = a.table_name
     outer apply (select column_name
                    from (
                          select rownum rn, column_name
                          from (
                                select b.column_name
                                  from all_ind_columns b
                                 where b.table_owner = a.table_owner
                                   and b.table_name  = a.table_name
                                   and b.index_name  = a.index_name
                                order by b.column_name
                               )
                         )
                  where rn = 2) col2
     outer apply (select index_name
                    from (
                          select rownum rn, index_name
                            from (
                                  select b.index_name
                                    from all_indexes b
                                   where b.table_owner = a.table_owner
                                     and b.table_name  = a.table_name
                                     and b.uniqueness  = a.uniqueness
                                  order by b.index_name
                                 )
                         )
                  where rn = 2) i2
where t.owner = 'HR'
order by a.table_name, a.uniqueness, a.index_name
...
Рейтинг: 0 / 0
Помогите, пожалуйста, решить задачу
    #39912488
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Практически не тестировал. Проверяйте-правьте самостоятельно.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
with t (table_name, index_owner, index_name, uniqueness, n_cols, index_col)
   as (
select i.table_name, i.owner, i.index_name, i.uniqueness
     , count(column_name) n_cols
     , case i.uniqueness
       when 'NONUNIQUE' then min(column_name) --first_col
       when 'UNIQUE' then regexp_substr(listagg(column_name,';') within group (order by column_name),'[^;]+',1,2) --second_col
       end index_col
  from all_indexes i, all_ind_columns ic
 where i.table_owner = user
   and (i.table_owner, i.table_name, i.owner, i.index_name) = any((ic.table_owner, ic.table_name, ic.index_owner, ic.index_name))
 group by i.table_owner, i.table_name, i.owner, i.index_name, i.uniqueness
)
select *
  from t
 pivot( min(index_name) as idx_name
      , min(n_cols) keep (dense_rank first order by index_name) as n_of_cols
      , min(index_col) keep (dense_rank first order by index_name) idx_col
      , count(distinct index_name) as n_of_indexes
 for uniqueness in( 'NONUNIQUE' non_unq
                  , 'UNIQUE' unq)
 ) x

...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите, пожалуйста, решить задачу
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]