СЛУ запросом SQL
От: naf2000  
Дата: 26.02.10 10:38
Оценка: 15 (2) :))
Возможно ли решить систему линейных уравнений запросом?
Дано:
— таблица А с тремя полями: номер строки, номер столбца, коэффициент
— таблица Б с двумя полями: номер строки, свободный член
— все значения заполнены
— система имеет единственное решение
Требуется:
вывести набор данных из двух столбцов: номер переменной, значение.
Текст запроса не должен зависеть от количества переменных. Без использования процедурных расширений SQL. Один запрос SELECT ...
Re: СЛУ запросом SQL
От: wildwind Россия  
Дата: 26.02.10 15:10
Оценка:
Здравствуйте, naf2000, Вы писали:

N>Возможно ли решить систему линейных уравнений запросом?


Собеседование? Где такое дают?
Re: СЛУ запросом SQL
От: rus blood Россия  
Дата: 28.02.10 08:20
Оценка:
Здравствуйте, naf2000, Вы писали:

N>Возможно ли решить систему линейных уравнений запросом?

N>Дано:
N>- таблица А с тремя полями: номер строки, номер столбца, коэффициент
N>- таблица Б с двумя полями: номер строки, свободный член
N>- все значения заполнены
N>- система имеет единственное решение
N>Требуется:
N>вывести набор данных из двух столбцов: номер переменной, значение.
N>Текст запроса не должен зависеть от количества переменных. Без использования процедурных расширений SQL. Один запрос SELECT ...

метод Крамера?
Имею скафандр — готов путешествовать!
Re[2]: СЛУ запросом SQL
От: dilmah США  
Дата: 28.02.10 17:21
Оценка:
N>>Текст запроса не должен зависеть от количества переменных. Без использования процедурных расширений SQL.

RB>метод Крамера?


разве SQL умеет рекурсивно подзапросы делать?
Re[3]: СЛУ запросом SQL
От: rus blood Россия  
Дата: 01.03.10 05:35
Оценка:
Здравствуйте, dilmah, Вы писали:

D>разве SQL умеет рекурсивно подзапросы делать?


И не надо делать рекурсию.
Есть таблица B, которая дает размер матрицы и позволяет организовать счетчики.
Имею скафандр — готов путешествовать!
Re[4]: СЛУ запросом SQL
От: lost_guadelenn  
Дата: 01.03.10 14:08
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>И не надо делать рекурсию.

RB>Есть таблица B, которая дает размер матрицы и позволяет организовать счетчики.
Было бы интересно увидеть реализацию нахождения определителя произвольного размера на SQL. :]
Re[5]: СЛУ запросом SQL
От: umnik  
Дата: 05.03.10 00:21
Оценка:
Здравствуйте, lost_guadelenn, Вы писали:

_>Здравствуйте, rus blood, Вы писали:


RB>>И не надо делать рекурсию.

RB>>Есть таблица B, которая дает размер матрицы и позволяет организовать счетчики.
_>Было бы интересно увидеть реализацию нахождения определителя произвольного размера на SQL. :]
Методом Гаусса?
Re: СЛУ запросом SQL
От: Кодт Россия  
Дата: 05.03.10 11:01
Оценка:
Здравствуйте, naf2000, Вы писали:

Можно отвлечься от SQL и попробовать похожее задание:
найти определитель матрицы, используя только ZF-нотацию и свёртки.
Перекуём баги на фичи!
Re: СЛУ запросом SQL
От: Овощ http://www.google.com
Дата: 10.03.10 01:30
Оценка:
Здравствуйте, naf2000, Вы писали:

N>Возможно ли решить систему линейных уравнений запросом?

N>Дано:
N>- таблица А с тремя полями: номер строки, номер столбца, коэффициент
N>- таблица Б с двумя полями: номер строки, свободный член
N>- все значения заполнены
N>- система имеет единственное решение
N>Требуется:
N>вывести набор данных из двух столбцов: номер переменной, значение.
N>Текст запроса не должен зависеть от количества переменных. Без использования процедурных расширений SQL. Один запрос SELECT ...

У меня чуть-чуть получилось.
СУБД — Oracle 10g Express. Метод Крамера для решения системы + метод Лейбница для нахождения детерминанта.
К сожелению получилось не очень производительное решение. Для размеров меньше 7 находит решение меньше чем за секунду. Для n=7 ~ примерно за 2 с половиной минуты. БОльшие размерности не осиливает.

create table matrix(nrow integer, ncol integer, val number);
create table coef(nrow integer, val number);

with mrank as
(
    select count(*) as r
    from coef
),
rankgenerator as
(
    select rownum as rn
    from dual, mrank
    connect by level <= mrank.r
),
matrixfordeterminant as
(
    select rg.rn, matrix.nrow, matrix.ncol,
        case
            when rg.rn = matrix.ncol then coef.val
            else matrix.val
        end as val
    from matrix
    inner join coef on matrix.nrow = coef.nrow    
    cross join
    (
        select rankgenerator.rn from rankgenerator
        union all
        select 0 from dual
    ) rg
),
lengthcount as
(
    select sum(length(rn)) + count(rn) lencnt
    from rankgenerator
),
permutations as
(
    select trim('/' from p) path
    from
    (
        select sys_connect_by_path (rn, '/') p
        from rankgenerator
        connect by nocycle prior rn != rn
    ) gen, lengthcount
    where length(p) = lengthcount.lencnt
),
permutationselements as
(
    select perm.path, rn.rn, to_number(regexp_substr(perm.path, '[^/]+', 1, rn.rn)) el
    from permutations perm
    cross join
    (
        select rownum as rn from dual, mrank connect by level <= mrank.r
    ) rn
),
permutation_sign as
(
    select permutations.path, 
           case
               when
                   mod
                   (
                       sum(permelem_rightmincount.rightmincount),
                       2
                   ) = 0
               then 1
               else -1
           end as psign
    from permutations inner join
    (
        select outer.path,
        (
            select count(*)
            from permutationselements inn
                where inn.path = outer.path
                and inn.rn > outer.rn
                and inn.el < outer.el
        ) rightmincount
        from permutationselements outer
    ) permelem_rightmincount
    on permutations.path = permelem_rightmincount.path
    group by permutations.path
),
determinants as
(
    select rn, sum(mul *
           (case when mod(msign, 2) = 0 then 1 else -1 end) *
           (case when mzero > 0 then 0 else 1 end)) det
    from
    (
        select matrixfordeterminant.rn,
               permutation_sign.psign*exp(sum(ln(abs(case when matrixfordeterminant.val = 0
                                                          then 0.01
                                                          else matrixfordeterminant.val
                                                     end)))) mul,
               sum(case when sign(matrixfordeterminant.val) = -1 then 1 else 0 end) msign,
               sum(case when matrixfordeterminant.val = 0 then 1 else 0 end) mzero
        from matrixfordeterminant
            inner join permutationselements
                on matrixfordeterminant.nrow = permutationselements.rn
                and matrixfordeterminant.ncol = permutationselements.el
            inner join permutation_sign
                on permutation_sign.path = permutationselements.path
        group by matrixfordeterminant.rn, permutationselements.path, permutation_sign.psign
    )
    group by rn
)
select determinants.rn, determinants.det/(select determinants.det from determinants where rn = 0)
from determinants
where determinants.rn != 0
order by determinants.rn


Я думаю надо пробовать делать через CTE — оно больше для этого подходит.
Re[2]: СЛУ запросом SQL
От: umnik  
Дата: 10.03.10 02:56
Оценка: +1
Здравствуйте, Овощ, Вы писали:

"Без использования процедурных расширений SQL. Один запрос SELECT"?
Re[3]: СЛУ запросом SQL
От: Овощ http://www.google.com
Дата: 10.03.10 08:06
Оценка:
Здравствуйте, umnik, Вы писали:

U>"Без использования процедурных расширений SQL. Один запрос SELECT"?


Ну да. Именно вот так. И пусть вас не смущает subquery factoring (with clause). Она нужна только лишь чтобы поименовать отдельные части запроса и сделать его более понятным. Избавиться от них можно просто механически подставив соответсвующие subquery вместо их имен во всем запросе.
В версии до 11gR2 оно ни на что большее не способно к сожалению.
В вот в MS Sql Server (CTE) или в Oracle 11gR2 (Recursive Subquery Factoring) оно уже может быть рекурсивным, что позволяет делать более интересные вещи. Хотя и они остаются в рамках "один запрос select", потому что они являются составной частью оператора select даже по стандарту ANSI.