Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Вывод уникальных записей / 19 сообщений из 19, страница 1 из 1
15.09.2020, 18:23
    #39998945
mayapple
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
Добрый день. Прошу помочь с такой задачей:

Есть таблица:
ID_out ID_in Vol
1001 1004 98
1001 1005 1
1002 1005 83
1002 1005 10

Нужно вывести уникальные записи по ключу id_out и id_in, а для дублирующих строк, таких как
1002 1005 83
1002 1005 10
взять любую значение которой vol<40 если таковая имеется.
Решение нужно одним запросом select

Ожидаю такой результат:
ID_out ID_in Vol
1001 1004 98
1001 1005 1
1002 1005 10

Заранее большое спасибо.
...
Рейтинг: 0 / 0
15.09.2020, 18:27
    #39998948
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
Min(case Vol <40 then Vol end) +
Group by ID_out, ID_in
...
Рейтинг: 0 / 0
15.09.2020, 20:00
    #39998989
mayapple
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
xtender,

попробовала так:
Код: sql
1.
2.
3.
4.
5.
select cm.id_out, cm.id_in, 
min(case when cm.vol<50 then cm.vol end) as vol
from table cm
where 1=1
group by cm.id_out, cm.id_in



результат совсем не тот
1001 1004 null
1001 1002 null
1002 1005 10
1001 1005 1
...
Рейтинг: 0 / 0
15.09.2020, 20:04
    #39998992
Lary Denis
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
mayapple,
может условие фильтрации не сработало?
...
Рейтинг: 0 / 0
15.09.2020, 20:05
    #39998994
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
mayapple,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
select
  cm.id_out, cm.id_in, 
  case 
     when count(*)=1 
        then min(vol) 
     else min(case when cm.vol<50 then cm.vol end)
  end as vol
from cm
where 1=1
group by cm.id_out, cm.id_in
order by 1,2 


Код: 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.
with cm(ID_out,ID_in,Vol) as (
select 1001, 1004, 98 from dual union all
select 1001, 1005, 1 from dual union all
select 1002, 1005, 83 from dual union all
select 1002, 1005, 10 from dual 
)
select
  cm.id_out, cm.id_in, 
  case 
     when count(*)=1 
        then min(vol) 
     else min(case when cm.vol<50 then cm.vol end)
  end as vol
from cm
where 1=1
group by cm.id_out, cm.id_in
order by 1,2;

    ID_OUT      ID_IN        VOL
---------- ---------- ----------
      1001       1004         98
      1001       1005          1
      1002       1005         10

3 rows selected.
...
Рейтинг: 0 / 0
15.09.2020, 20:11
    #39998998
mayapple
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
xtender,

спасибо! я была близка с case, но подумала что есть какая-то секретная функция или оператор которые мне не известны и сдалась.
...
Рейтинг: 0 / 0
15.09.2020, 20:22
    #39999002
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
mayapple
xtender,

спасибо! я была близка с case, но подумала что есть какая-то секретная функция или оператор которые мне не известны и сдалась.


Наверное, есть. Но если это для профессора, пожалейте его старые глаза.

Код: plsql
1.
2.
3.
select    ID_out, ID_in, min(Vol) from tbl 
 group by ID_out, ID_in 
 order by ID_out, ID_in

Модератор: Предупреждение: не надо давать заведомо неправильные ответы
...
Рейтинг: 0 / 0
15.09.2020, 20:59
    #39999030
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
Давайте посмотрим вместе, я тоже учусь.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SQL> with tbl as (
  2  select 1001 as ID_out, 1004 as ID_in, 98 as Vol from dual union all
  3  select 1001, 1005, 1  from dual union all
  4  select 1002, 1005, 83 from dual union all
  5  select 1002, 1005, 10 from dual)
  6  select ID_out, ID_in, min(Vol) from tbl group by ID_out, ID_in order by ID_out, ID_in
  7  /
    ID_OUT      ID_IN   MIN(VOL)
---------- ---------- ----------
      1001       1004         98
      1001       1005          1
      1002       1005         10



Ответ правильный (это конечно еще не значит что код правильный).
(1)Нужно вывести уникальные записи по ключу id_out и id_in
условие выполняется
(2) для дублирующих строк взять любую значение которой vol<40
выводит < 40, если такая имеется
(3) Решение нужно одним запросом select
условие выполняется.

Вроде все в порядке.
...
Рейтинг: 0 / 0
15.09.2020, 21:02
    #39999032
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
НеофитSQL
Вроде все в порядке.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
SQL> with tbl as (
  2  select 1001 as ID_out, 1004 as ID_in, 98 as Vol from dual union all
  3  select 1001, 1005, 1  from dual union all
  4  select 1002, 1005, 83 from dual union all
  4  select 1003, 1005, 128 from dual union all
  4  select 1003, 1005, 256 from dual union all
  5  select 1002, 1005, 10 from dual)
  6  select ID_out, ID_in, min(Vol) from tbl group by ID_out, ID_in order by ID_out, ID_in
  7  /
...
Рейтинг: 0 / 0
15.09.2020, 21:15
    #39999037
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
mayapple
дублирующих строк, таких как
1002 1005 83
1002 1005 10
взять любую значение которой vol<40 если таковая имеется.

Это условие можно интерпретировать иначе, чем xtender: не выбирать дубли если среди них отсутствует запись, отвечающая критерию vol<40 (вариант Саяна даст запись с незаполненным Vol)
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
with tbl as (
select 1001 as ID_out, 1004 as ID_in, 98 as Vol from dual union all
select 1001, 1005, 1  from dual union all
select 1002, 1005, 83 from dual union all
select 1003, 1005, 128 from dual union all
select 1003, 1005, 256 from dual union all
select 1002, 1005, 10 from dual)
select ID_out
     , ID_in
     , min(Vol)
--     , min(Vol) keep (dense_rank first order by vol) -- предпочтительно в случае, когда требуется выбрать более одного атрибута "любой записи"
  from tbl 
 group by ID_out, ID_in 
having 1 = count(*) -- нет дублей
    or min(vol) < 40  -- или есть запись(и) vol<40
 order by ID_out, ID_in
...
Рейтинг: 0 / 0
15.09.2020, 21:19
    #39999041
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
andrey_anonymous,

Как всегда продуктивно.

Тут дело в интерпретации неполного условия "для дублирующих строк взять любую значение которой vol<40".

Если оно продолжается "а если нет < 40, то любую", мое решение верное

Если оно продолжается "а если нет < 40, то выведи null после ID_out, ID_in", то версия xtender верная

Если оно продолжается "а если нет < 40, то не выводи строку", то нужно третье решение, эти два не годятся.
...
Рейтинг: 0 / 0
15.09.2020, 21:23
    #39999042
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
НеофитSQL
Если оно продолжается "а если нет < 40, то любую", мое решение верное

Не согласен.
Ваше предположение сводится к условию "минимальное по группе, и пофиг какое"
В постановке же специально оговорена граница 40.
...
Рейтинг: 0 / 0
15.09.2020, 21:26
    #39999044
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
andrey_anonymous,

А, вот и третье решение появилось пока я ответ писал.

>> 1 = count(*)

Мне кажется, или это долгие годы C++ наложили отпечаток?
...
Рейтинг: 0 / 0
15.09.2020, 21:31
    #39999047
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
Вам кажется.
Это отпечаток долгих лет sql.
...
Рейтинг: 0 / 0
15.09.2020, 21:37
    #39999049
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
andrey_anonymous
НеофитSQL
Если оно продолжается "а если нет < 40, то любую", мое решение верное

Не согласен.
Ваше предположение сводится к условию "минимальное по группе, и пофиг какое"
В постановке же специально оговорена граница 40.


Я постараюсь показать тождественность*, как применимо к этой задаче, предполагая что "а если нет < 40, то любую" есть условие.

решим перебором для двух чисел.

числа а,б - числа меньше 40, а < б
числа Д,Е - больше или равны 40, Д < Е

Код: plaintext
1.
2.
3.
4.
5.
 1    2           min       Выполнено?
---------------------------------------
 а    б             а         Да, любое <40
 а,   Д             а         Да, любое < 40
 Д,   Е             Д         Да, любое.

Для произвольного числа больше 2х задача тривиально сводится к двум.

(*) min более строгий критерий, если быть точным.
...
Рейтинг: 0 / 0
15.09.2020, 21:45
    #39999052
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
НеофитSQL
min более строгий критерий, если быть точным.

Запись с минимальным значением vol отвечает критерию "любая" так же, как и любая другая.
В этой связи Ваша интерпретация просто аннулирует требование по граничному значению vol для подмножества строк с мощностью > 1, поэтому я не принял бы Ваш вариант в качестве решения несмотря на наукообразность отмазки.
...
Рейтинг: 0 / 0
15.09.2020, 22:03
    #39999062
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
andrey_anonymous,

Я еще подумал, но все таки не согласен.

Граничное условие задано, согласен.
Я заменил это граничное условие более строгим, которое не упоминает 40, но выполняет условие.
Что может быт не интуитивно, потому что число 40 вроде как пропало, а оно казалось важным.

Я попробую по-другому.
"Маша, дай мне одну сливу из корзинки, меньше 40 граммов, если есть такие, и дай любую, если все больше 40"
(Маша достает наименьшую сливу).

Если эта слива < 40г, я получил что просил, претензий нет.
Если эта слива >= 40, значит в корзинке нет ничего меньше. Претензий снова нет.

Маша, будучи подкована в математике, упростила задачу заменив ее на более строгую.
Зато теперь ей не нужны точные весы с указанием граммов, и ее алгоритм годится для любой границы: 40, 50, и т.д.
...
Рейтинг: 0 / 0
15.09.2020, 22:11
    #39999065
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
НеофитSQL
которое не упоминает 40, но выполняет условие.

Попробую по-другому: я видел много постановок и много реализаций.
Подобные границы в постановках исходят от бизнеса.
Попытка "оптимизировать" постановку методами "мне так проще" или "я так вижу" обычно приводит к рекламации и необходимости переделывать, поскольку до разраба редко доводят весь контекст задачи.
...
Рейтинг: 0 / 0
15.09.2020, 22:31
    #39999072
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вывод уникальных записей
Ну разве так, чтоб контекст в коде не терять на случай передумал/недослышал.

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


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