2017-02-10 14 views
1

Я использую Oracle (разработчик SQL). Ниже Вы найдете пример и результата, который хотел бы получить (цель выбрать, чтобы узнать людей, которые представили проект А и еще не сделали каких-либо действий в проекте В еще):ORACLE MAX GROUP BY

данных таблицы:

CREATE TABLE "XXX"."TABLE1" 
    ( "STATUS" VARCHAR2(20 BYTE), 
     "PROJECT_NAME" VARCHAR2(20 BYTE), 
    "VERSION_NUMBER" NUMBER, 
    "PERSON" VARCHAR2(20 BYTE) 
    ); 
Insert into XXX.TABLE1 (STATUS,PROJECT_NAME,VERSION_NUMBER,PERSON) values ('SUBMITTED','A','0','PETER'); 
Insert into XXX.TABLE1 (STATUS,PROJECT_NAME,VERSION_NUMBER,PERSON) values ('SUBMITTED','A','0','JOHN'); 
Insert into XXX.TABLE1 (STATUS,PROJECT_NAME,VERSION_NUMBER,PERSON) values ('SUBMITTED','A','1','JOHN'); 
Insert into XXX.TABLE1 (STATUS,PROJECT_NAME,VERSION_NUMBER,PERSON) values ('NEW','A','2','JOHN'); 
Insert into XXX.TABLE1 (STATUS,PROJECT_NAME,VERSION_NUMBER,PERSON) values ('SUBMITTED','A','0','MARY'); 
Insert into XXX.TABLE1 (STATUS,PROJECT_NAME,VERSION_NUMBER,PERSON) values ('SUBMITTED','B','0','PETER'); 
Insert into XXX.TABLE1 (STATUS,PROJECT_NAME,VERSION_NUMBER,PERSON) values ('NEW','B','1','PETER'); 
Insert into XXX.TABLE1 (STATUS,PROJECT_NAME,VERSION_NUMBER,PERSON) values ('SUBMITTED','B','0','JOHN'); 

создания таблицы должен выглядеть следующим образом:

TABLE1: 
TABLE1.STATUS TABLE1.PROJECT_NAME TABLE1.VERSION_NUMBER TABLE1.PERSON 
SUBMITTED  A     0      PETER 
SUBMITTED  A     0      JOHN 
SUBMITTED  A     1      JOHN 
NEW    A     2      JOHN 
SUBMITTED  A     0      MARY 
SUBMITTED  B     0      PETER 
NEW    B     1      PETER 
SUBMITTED  B     0      JOHN 

Результат того, что я хочу получить это:

STATUS  PROJECT_NAME VERSION_NUMBER PERSON STATUS_1 PROJECT_NAME_1 VERSION_NUMBER_1 PERSON_1 
SUBMITTED A    0    PETER NEW   B    1     PETER 
SUBMITTED A    1    JOHN SUBMITTED B    0     JOHN 
SUBMITTED A    0    MARY     

Select, который я использую сейчас:

select t.*,v.* 
from TABLE1 t 
left outer join (select u.* 
    from TABLE1 u 
where exists (select max(z.VERSION_NUMBER) 
,z.PERSON 
,z.PROJECT_NAME 
    from TABLE1 z 
    where z.PROJECT_NAME = 'B' 
    and u.PROJECT_NAME = z.PROJECT_NAME 
    and u.PERSON = z.PERSON 
group by z.PERSON, z.PROJECT_NAME 
having u.VERSION_NUMBER = max(z.VERSION_NUMBER))) v 
on t.PERSON = v.PERSON 
where exists (select max (w.VERSION_NUMBER) 
,w.PERSON 
,w.PROJECT_NAME 
from TABLE1 w 
where w.PROJECT_NAME = 'A' 
and w.STATUS = 'SUBMITTED' 
and t.PROJECT_NAME = w.PROJECT_NAME 
and t.PERSON = w.PERSON 
group by w.PERSON, w.PROJECT_NAME 
having t.VERSION_NUMBER = max (w.VERSION_NUMBER)) 

ВОПРОС: Что было бы лучше (справа) способ написания такой выбора (лучшие практики), я должен лучше использовать аналитические функции или использовать что-то другое вместо EXISTS?

ответ

1

Я думаю, что вы слишком сложно это ...

WITH 
project_status (status, project_name, version_number, person) 
AS 
(SELECT 'SUBMITTED','A','0','PETER' FROM dual UNION ALL 
    SELECT 'SUBMITTED','A','0','JOHN' FROM dual UNION ALL 
    SELECT 'SUBMITTED','A','1','JOHN' FROM dual UNION ALL 
    SELECT 'NEW','A','2','JOHN' FROM dual UNION ALL 
    SELECT 'SUBMITTED','A','0','MARY' FROM dual UNION ALL 
    SELECT 'SUBMITTED','B','0','PETER' FROM dual UNION ALL 
    SELECT 'NEW','B','1','PETER' FROM dual UNION ALL 
    SELECT 'SUBMITTED','B','0','JOHN' FROM dual 
) 
SELECT DISTINCT 
ps.person 
,ps.project_name 
,ps.status 
FROM 
project_status ps 
WHERE 1=1 
AND ps.project_name = 'A' 
AND ps.status = 'SUBMITTED' 
AND NOT EXISTS 
(SELECT 1 
    FROM project_status ps2 
    WHERE ps2.person = ps.person 
    AND ps2.project_name = 'B' 
) 
; 
0

цель выбрать, чтобы узнать, людей, которые представили проект А и еще не сделали каких-либо действий в проекте В еще

Если ваша цель состоит в том, чтобы получить человек, вам не нужны полные строки. Один из способов ответить на этот вопрос заключается в использовании group by и having:

select t1.person 
from "XXX"."TABLE1" t1 
group by t1.person 
having sum(case when project_name = 'A' and status = 'New' then 1 else 0 end) > 0 and 
     sum(case when project_name = 'B' then 1 else 0 end) = 0; 

Если вам нужны полные строки, то христианин имеет разумное решение.

 Смежные вопросы

  • Нет связанных вопросов^_^