1 Востаннє редагувалося vitia444 (07.04.2015 00:20:54)

Тема: як обійти групування, коли воно синтаксично необхідне?

select usr_login, max(usr_birthyear) from "user"

Як видно - перша колонка не містить функції групування, а друга містить
Необхідно: з першої колонки витягти будь-яке поле, яке відповідає максимальному значенню року народження
P.S. бажано до таблички "user" звертатись лише один раз

Поточне рішення:

select 
  usr_login, 
  usr_birthyear 
from (
         Select usr_login, usr_birthyear from "user"
         order by usr_birthyear desc)
where rownum = 1;

Відповідь на питання "Нащо?":
В реальності використовується інша таблиця table1, а  те саме поле usr_birthyear є обчислювальним із немаленькою складністю, і кількість останнього бажано мінімізувати. У наведеному рішенні поле обчислюється лише перший раз, другий - воно вже обчислене.

2 Востаннє редагувалося koala (07.04.2015 06:35:03)

Re: як обійти групування, коли воно синтаксично необхідне?

То зробіть це поле необчислюваним.
От же люблять люди в 1НФ не вписуватися, а потім милиці ставити...

3

Re: як обійти групування, коли воно синтаксично необхідне?

Вибачте, але явно що ви щось городите складніше, ніж вимагає ваша задача. В такому разі треба докладніше описати умови задачі та навести приклад вхідних даних. А з іншої сторони - у вас же є начебто й розв'язок вашої задачі, що у ньому не так?

Далі - мені складно зрозуміти що це за "поле usr_birthyear є обчислювальним із немаленькою складністю" - ви його парсите з якогось текста? Якщо так, то створіть окреме поле usr_birthyear і не обчислюйте його за кожним разом.

4

Re: як обійти групування, коли воно синтаксично необхідне?

Але ж ви люди дивні... Питаю як задачу можна краще рішити, вони до умови придираються...

Повна задача:
є БД клієнтських карток, у якому є таблиця "захворювання", яка містить номер захворювання, дату початку, логін користувача та ще кілька полів, які не мають відношення до задачі. Усі симптоми (вони ж значення певних характеристик, або клінічні прояви) рознесені ще по кількох таблицях, які містять FK "номер захворювання", номер дня зазначення характеристики починаючи з дати початку захворювання та власне значення характеристики(наприклад, температура тіла). Задача - потрібно для заданого захворювання найти найбільш схоже. Тому є функція FUNC, яка визначає рівень схожості одного захворювання з іншим і створюється через select табличка із двома полями "ill_num" та "similarity_degree", де останнє - результат тої функції. Сама функція працює по нечіткій логіці, не сильно складно, але не хотілося б всю базу заново перераховувати. Залишилось лише вибрати номер, значення функції якого є максимальним.

5

Re: як обійти групування, коли воно синтаксично необхідне?

koala написав:

От же люблять люди в 1НФ не вписуватися, а потім милиці ставити...

Де саме порушення? Хай навіть це таблиця USER, ключ є - usr_login, неатомарних даних немає, стовпчики не повторюються... Вся БД недавно була нормалізована до 4-го рівня, поки я не вирішив пару трійку атрибутів дописати...

6

Re: як обійти групування, коли воно синтаксично необхідне?

Це все круто. А usr_birthyear як обчислюється, ви так і не сказали.

Подякували: ktretyak, quez2

7 Востаннє редагувалося vitia444 (08.04.2015 11:40:03)

Re: як обійти групування, коли воно синтаксично необхідне?

koala написав:

Це все круто. А usr_birthyear як обчислюється, ви так і не сказали.

І знову просто придирання до умови задачі....

Можливо я неправильно пояснив, вся робота із "User" на початку теми - це було абстрагування основної задачі, яку я описав постом вище, тобто
"user" => select ill_num, func1(ill_num) similarity_degree from ills
usr_name => ill_num
usr_birthyear => func1(ill_num)

Та й до того ж Ви так і не сказали, де порушення нормалізації

8

Re: як обійти групування, коли воно синтаксично необхідне?

Порушення нормалізації було б в тому, що usr_birthyear зберігалося, ймовірно, як частина поля. Порушення атомарності. Не придирайтеся до моїх слів, якщо вже вимагаєте, щоб я до ваших не придирався.
А тут варто було б перепродумати, як працює  func1 similarity_degree from.

9

Re: як обійти групування, коли воно синтаксично необхідне?

Я о от в кром загнав і створив результуючу таблицю де вже були би результати роботи функції готові.

10

Re: як обійти групування, коли воно синтаксично необхідне?

Vo_Vik написав:

Я о от в кром загнав і створив результуючу таблицю де вже були би результати роботи функції готові.

Питання не в тому, як створити таблицю, а в тому, як витягти номер із максимальним значенням функції так, щоб обраховувати таблицю лише раз

11

Re: як обійти групування, коли воно синтаксично необхідне?

vitia444 написав:
Vo_Vik написав:

Я о от в кром загнав і створив результуючу таблицю де вже були би результати роботи функції готові.

Питання не в тому, як створити таблицю, а в тому, як витягти номер із максимальним значенням функції так, щоб обраховувати таблицю лише раз

Я у вас вже питав, але так і не отримав відповіді... Ви ж надали в своєму першому повідомленні робочий варіант, який самі ж і описали, що обрахунок буде лише перший раз, а на другий раз вже буде звернення до тимчасової таблиці (на скільки я розумію, то це запит до Oracle, то мабуть в ньому теж для внутрішнього запиту створюється окрема темпова таблиця)

12 Востаннє редагувалося vitia444 (09.04.2015 14:06:46)

Re: як обійти групування, коли воно синтаксично необхідне?

ktretyak написав:

Ви ж надали в своєму першому повідомленні робочий варіант, який самі ж і описали, що обрахунок буде лише перший раз, а на другий раз вже буде звернення до тимчасової таблиці (на скільки я розумію, то це запит до Oracle, то мабуть в ньому теж для внутрішнього запиту створюється окрема темпова таблиця)

Ну раз я написав своє поточне рішення, то, можливо, я очікую що хтось здогадається більш оптимальне, без створення тимчасової таблиці і сортування.

13 Востаннє редагувалося ktretyak (09.04.2015 14:30:41)

Re: як обійти групування, коли воно синтаксично необхідне?

vitia444 написав:

Ну раз я написав своє поточне рішення, то, можливо, я очікую що хтось здогадається більш оптимальне, без створення тимчасової таблиці і сортування.

Якщо дотримуватись вашої вимоги "без групування", то тільки сортуванням тут можна обійтись. Тут дійсно оптимальнішим може бути використовувати саме групування, хоча функції прийдеться виконуватись двічі.

select
  m.max_ill_num
  ,i.*
from
(
  select
    max(func1(ill_num)) as max_ill_num
  from ills
) as m
  join ills as i
    on m.max_ill_num = func1(i.ill_num)
where rownum = 1;

Але найоптимальніше, звичайно ж - це створення поля в таблиці ills, де буде зберігатись результат виконання функції func1(i.ill_num)

14 Востаннє редагувалося vitia444 (09.04.2015 15:30:28)

Re: як обійти групування, коли воно синтаксично необхідне?

ktretyak написав:

Якщо дотримуватись вашої вимоги "без групування", то тільки сортуванням тут можна обійтись. Тут дійсно оптимальнішим може бути використовувати саме групування, хоча функції прийдеться виконуватись двічі.

select
  m.max_ill_num
  ,i.*
from
(
  select
    max(func1(ill_num)) as max_ill_num
  from ills
) as m
  join ills as i
    on m.max_ill_num = func1(i.ill_num)
where rownum = 1;

Але найоптимальніше, звичайно ж - це створення поля в таблиці ills, де буде зберігатись результат виконання функції func1(i.ill_num)

Цікавий варіант, Ви відійшли від сортування, але двічі обчислюєте таблицю...
А взагалі цікаве питання - що буде швидше, відсортувати велику таблицю, при цьому обчислення функції буде раз на рядок, чи шукати двічі цю функцію, але обійтись вибором максимуму...

функція лінійна, просто трохи довгенька, і має два вхідних параметри, про що раніше не сказав, там другий параметр - рядок, з яким іде порівняння, тому просто створити нову таблицю... OLAP цю проблему вирішив бив, але це для мене поки щось невідоме...

15

Re: як обійти групування, коли воно синтаксично необхідне?

vitia444 написав:
Vo_Vik написав:

Я о от в кром загнав і створив результуючу таблицю де вже були би результати роботи функції готові.

Питання не в тому, як створити таблицю, а в тому, як витягти номер із максимальним значенням функції так, щоб обраховувати таблицю лише раз

Не треба обраховувати взагалі при вибірці. Зробити крон, який буде обраховувати всі значення фунції і результати записувати в таблицю. Відповідно при вибірці не треба буде перераховувати ту фунцію взагалі.

16

Re: як обійти групування, коли воно синтаксично необхідне?

Vo_Vik написав:
vitia444 написав:
Vo_Vik написав:

Я о от в кром загнав і створив результуючу таблицю де вже були би результати роботи функції готові.

Питання не в тому, як створити таблицю, а в тому, як витягти номер із максимальним значенням функції так, щоб обраховувати таблицю лише раз

Не треба обраховувати взагалі при вибірці. Зробити крон, який буде обраховувати всі значення фунції і результати записувати в таблицю. Відповідно при вибірці не треба буде перераховувати ту фунцію взагалі.

Vitia444 написав:

функція має два вхідних параметри, про що раніше не сказав, там другий параметр - рядок, з яким іде порівняння, тому просто створити нову таблицю...

17 Востаннє редагувалося vitia444 (09.04.2015 16:32:59)

Re: як обійти групування, коли воно синтаксично необхідне?

vitia444 написав:
Vo_Vik написав:
vitia444 написав:

Питання не в тому, як створити таблицю, а в тому, як витягти номер із максимальним значенням функції так, щоб обраховувати таблицю лише раз

Не треба обраховувати взагалі при вибірці. Зробити крон, який буде обраховувати всі значення фунції і результати записувати в таблицю. Відповідно при вибірці не треба буде перераховувати ту фунцію взагалі.

vitia444 написав:

функція має два вхідних параметри, про що раніше не сказав, там другий параметр - рядок, з яким іде порівняння, тому просто створити нову таблицю...

18

Re: як обійти групування, коли воно синтаксично необхідне?

Відредагував, називається...

19

Re: як обійти групування, коли воно синтаксично необхідне?

Ну чого ж, можна створити таблицю типу, рядок1, рядок2, результат функції.

20

Re: як обійти групування, коли воно синтаксично необхідне?

Vo_Vik написав:

Ну чого ж, можна створити таблицю типу, рядок1, рядок2, результат функції.

А гроші на обладнання мені Ви дасте?
Якби це була таблиця, в яку записи заносилися б досить рідко - то я ще може над цим подумав би...
Я, звісно, розумію що це звичайна лаба, звичайний проект, але це не дозволяє мені бидлокодити, та ще й на стільки...