Oracle SQL — объединить строки с определенными свойствами

Я написал оператор SQL для экспорта результатов в таблицу Excel для аналитики. На данный момент у меня проблема:

Некоторые данные, которые разделены на 2 строки, но нуждаются в них как в 1 строке. Причиной этого является один столбец с разными значениями.

Я объясняю структуру: SQL создает эту таблицу (заголовки):

ROOT|INSERT_TS|COUNT_ALL|Order_Type|Input_Obj|Input_SUPP|IS_SIM|Last_TS|Status_Type|Count_Open

Пример данных с моей проблемой (это результат, который дает мой фактический SQL-оператор):

R |In_TS|C_AL|O|I_Obj|I_Supp|IS_Sim|La_TS|Status|C_Opn|
--+-----+----+-+-----+------+------+-----+------+-----+
76|date1|1451|a|file1|mass  |1     |date2|work  |1451 | <-- 1st part
76|date1|25  |a|file1|mass  |1     |date2|final |0    | <-- 2nd part
76|date1|1   |b|file1|man   |0     |date2|final |0    |
76|date1|1   |c|file1|mass  |1     |date2|work  |1    |

В конце я хочу это (моя цель после исправления SQL-запроса):

R |In_TS|C_AL|O|I_Obj|I_Supp|IS_Sim|La_TS|Status|C_Opn|
--+-----+----+-+-----+------+------+-----+------+-----+
76|date1|1476|a|file1|mass  |1     |date2|work  |1451 | <-- 1 row
76|date1|1   |b|file1|man   |0     |date2|final |0    |
76|date1|1   |c|file1|mass  |1     |date2|work  |1    |

Это мой фактический запрос/оператор sql:

SELECT 
  distinct t1.ROOT r, 
  min(to_char(t1.INSERT_TS, 'YYYY.MM.DD HH24:MI')) in_ts,
  count(distinct t1.tool_ID) c_al, -- this count give the number of modul steps in this "business tool" - no sum task is here needed
  t1.ORDERTYPE o,
  t1.I_OBJ,
  t1.I_Supp, 
  t1.IS_SIM, 
  max(to_char(t1.LASTCHANGE_TS, 'DD.MM.YYYY HH24:MI')) la_ts,
  t2.STATUS status,
  sum(case when t2.STATUS != 'final' then 1 else 0 end) c_opn
FROM TOOL_DATA.FW_MAIN t1
left join TOOL_DATA.CONF_STATUS t2 on t2.tab = 'FW_MAIN' and t2.status_val = t1.status
GROUP BY 
  t1.ROOT, t1.ORDERTYPE, t1.I_OBJ, t1.I_SUPP, t1.I_SIM, t2.STATUS
ORDER BY 2 desc, 1 desc
;

Что я делаю и ищу, чтобы решить эту проблему самостоятельно:

Смотрю тут в этом сообществе и в гугле, нашел какую-то задачу про собственные функции определения и listagg, но и то, и другое не помогает, потому что колонка "Статус" выросла, а ряд не совмещается.

Есть ли у кого-нибудь здесь какие-либо идеи для меня, чтобы решить эту проблему?

Важно следующее:

  • Колонка "О" идентична
  • Колонка "R" идентична
  • Столбец "IS_SIM" идентичен
  • Колонка "C_AL" является кумулятивной.
  • Col «C_Opn» суммирует только не «окончательные» наборы данных (лучше: оба значения суммируются, потому что xx + 0 = xx)
  • Столбец «Статус» показывает только «рабочее» значение, если строки объединены, «финальное» значение удаляется.

Решение (спасибо ruudvan)

SELECT 
  distinct t1.ROOT r, 
  min(to_char(t1.INSERT_TS, 'YYYY.MM.DD HH24:MI')) in_ts,
  count(distinct t1.tool_ID) c_al, -- this count give the number of modul steps in this "business tool" - no sum task is here needed
  t1.ORDERTYPE o,
  t1.I_OBJ,
  t1.I_Supp, 
  t1.IS_SIM, 
  max(to_char(t1.LASTCHANGE_TS, 'DD.MM.YYYY HH24:MI')) la_ts,
  NVL(MAX(case when t2.STATUS != 'final' then t2.STATUS else null end), 'final'), -- i set it to != 'final', because status have more as 1 work value, but i wrote it here for a simple view
  sum(case when t2.STATUS != 'final' then 1 else 0 end) c_opn
FROM TOOL_DATA.FW_MAIN t1
left join TOOL_DATA.CONF_STATUS t2 on t2.tab = 'FW_MAIN' and t2.status_val = t1.status
GROUP BY 
  t1.ROOT, t1.ORDERTYPE, t1.I_OBJ, t1.I_SUPP, t1.I_SIM,
ORDER BY 2 desc, 1 desc
;

person Lycann H. Faye    schedule 26.02.2015    source источник
comment
Поскольку все столбцы GROUP BY также находятся в списке выбора, вы можете удалить DISTINCT.   -  person jarlh    schedule 26.02.2015
comment
Обычно это возможно @jarlh , но не здесь, когда эта БД регистрирует бизнес-процессы. Если я это сделаю, я получу больше строк, которые мне нужны для аналитики. Я проверяю это, и это важно;) Но спасибо.   -  person Lycann H. Faye    schedule 26.02.2015
comment
Вопрос сбивает с толку, потому что проблемный набор данных, который вы нам показали, на самом деле является результатом запроса в вопросе. Вы бы получили более точные ответы, если бы показали нам фактический набор данных, на котором вы выполняете запрос и получаете результат, который хотите исправить дальше. Смотрите мой ответ независимо.   -  person ruudvan    schedule 26.02.2015
comment
Спасибо за эту информацию и типп ruudvan. Я включу это в свои следующие вопросы.   -  person Lycann H. Faye    schedule 26.02.2015
comment
Я редактирую этот вопрос здесь с дополнительной информацией, надеюсь, теперь это более понятно   -  person Lycann H. Faye    schedule 26.02.2015


Ответы (2)


Начните с этого -

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

Поэтому удалите t2.STATUS из предложения GROUP BY. Вместо этого замените

SELECT ... t2.STATUS

to

SELECT ... NVL(MAX(case when t2.STATUS = 'work' then t2.STATUS else null end), 'final')

Здесь case when t2.STATUS = 'work' then t2.STATUS else null end будет гарантировать, что все значения в той же группе, которые имеют статус «окончательный», будут нулевыми, а «рабочие» значения останутся как есть. Выполнение MAX (или MIN) для них выберет ненулевое значение, которое будет «работать».

Однако, если «рабочее» значение отсутствует: NVL гарантирует, что если все значения являются «окончательными», то MAX() приведет к нулевому значению, и в этом случае в качестве результата будет возвращено «финальное».

SELECT ... COUNT(distinct t1.tool_id) c_al останется прежним, так как теперь будет учитываться tool_id для всей группы.

person ruudvan    schedule 26.02.2015
comment
Да, это было решением. Большое спасибо @ruudvan !! - person Lycann H. Faye; 26.02.2015

Попробуй это:-

SELECT 
distinct t1.ROOT r, 
min(to_char(t1.INSERT_TS, 'YYYY.MM.DD HH24:MI')) in_ts,
sum(distinct t1.tool_ID) c_al,
t1.ORDERTYPE o,
t1.I_OBJ,
t1.I_Supp, 
t1.IS_SIM, 
max(to_char(t1.LASTCHANGE_TS, 'DD.MM.YYYY HH24:MI')) la_ts,
t2.STATUS status,
sum(case when t2.STATUS != 'final' then 1 else 0 end) c_opn
FROM TOOL_DATA.FW_MAIN t1
left join TOOL_DATA.CONF_STATUS t2 on t2.tab = 'FW_MAIN' and t2.status_val = t1.status
GROUP BY t1.ROOT, t1.ORDERTYPE, t1.I_OBJ, t1.I_SUPP, t1.I_SIM, t2.STATUS
ORDER BY 2 desc, 1 desc;
person Ankit Bajpai    schedule 26.02.2015
comment
Это не помогает, потому что t1.tool_id - это большее число, но мне нужна не сумма этих номеров идентификаторов, мне нужна сумма количества tool_id (в информации: количество tool_id дает информацию о том, сколько модулей шаги, которые он дает в этом инструменте для обработки бизнес-заказа) - person Lycann H. Faye; 26.02.2015