Самостоятельное внутреннее соединение, совокупность и сумма набора - PullRequest
3 голосов
/ 28 мая 2020

У меня есть следующая схема:

CREATE TABLE aTable
    ("id" int, "idOfOperation" varchar(10), "uniqueName" varchar(6), "randomNumber" int)
;

INSERT INTO aTable
    ("id", "idOfOperation", "uniqueName", "randomNumber")
VALUES
    (1, 'operation1', 'model1', 3),
    (2, 'operation1', 'model2', 5),
    (3, 'operation2', 'model2', 43),
    (4, 'operation2', 'model3', 57),
    (5, 'operation2', 'model4', 65)
;

Ограничения:

  • (idOfOperation, uniqueName) уникальны.

Таблица содержит результаты различных операций (операция1, операция2) и какая операция имеет несколько подмоделей (модель1, модель2, модель3, модель4) с некоторыми уникальными значениями (randomNumber).

Что мне нужно для достижения:

  • Создайте запрос, который найдет сумму набора двух операций (операция1, операция2) со следующим выводом: 'model2', 5.18, 'model2', 43.2

Я уже пробовал следующее внутреннее соединение:

select r1.*, r2.*
from aTable r1
         inner join aTable r2
         on (r1."uniqueName" = r2."uniqueName" and r1."idOfOperation" != r2."idOfOperation")
where (r1."idOfOperation" = 'operation1' or r1."idOfOperation" = 'operation2')

Но результат содержит две строки вместо одной (с замененными значениями):

id  idOfOperation   uniqueName  randomNumber    id  idOfOperation   uniqueName  randomNumber
3   operation2  model2  43  2   operation1  model2  5
2   operation1  model2  5   3   operation2  model2  43

Ожидаемый результат:

operation2, operation1, model2, 43, 5

Я был бы очень признателен за любую помощь.

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Используйте запрос ниже,

select split_part(idOfOperation, ',', 2) as col1, split_part(idOfOperation, ',', 1) as 
col2,  uniqueName as col3, split_part(randomNumber, ',', 2) as col4, 
split_part(randomNumber, ',', 1) as col5 from
(select STRING_AGG ("idOfOperation", ',') as idOfOperation , "uniqueName" as 
uniqueName, STRING_AGG ("randomNumber"::text, ',') as randomNumber
from aTable  group by "uniqueName") qry where split_part(idOfOperation, ',', 2) != '';

Обрезка ожидаемого результата,

enter image description here

0 голосов
/ 28 мая 2020

Я так понимаю, вы ищете переходы с operation1 на operation2. Один из вариантов использует оконные функции: lead() и lag() позволяют получить доступ к следующей и предыдущей операции, которые затем можно использовать для фильтрации:

select "id", "idOfOperation", "uniqueName", "randomNumber"
from (
    select 
        t.*,
        lag("idOfOperation") over(order by id) lagIdOfOperation,
        lead("idOfOperation") over(order by id) leadIdOfOperation
    from aTable t
) t
where ('operation1', 'operation2') in (
    (t."idOfOperation",  leadIdOfOperation) , 
    (lagIdOfOperation, t."idOfOperation") 
)

Демо на DB Fiddle :

id | idOfOperation | uniqueName | randomNumber
-: | :------------ | :--------- | -----------:
 2 | operation1    | model2     |            5
 3 | operation2    | model2     |           43

Примечания:

  • избегайте использования идентификаторов в двойных кавычках (чувствительных к регистру): они просто усложняют задачу, например очевидного преимущества нет

  • столбец randomNumber, вероятно, должен быть numeric, а не int

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...