SQL и 2 сложное соединение

0

Я пытаюсь оптимизировать SQL-запрос с MySQL 5.5, в отношении 2 разделяет запросы. Я хотел бы иметь один запрос в конце, если это возможно.

У меня есть таблица DocumentType (см. Схему в конце этого вопроса). Например, я хотел бы отобразить "3 DocumentInstance на 5, загруженных для программы № 4".

Чтобы подсчитать общее количество документов для каждой программы, у меня есть этот запрос:

select p.id as programId, count(dt.id) as totalDocPerProgram
from DocumentType dt
join DocumentTypeInProgram dtip on dtip.documentType_id=dt.id
join Program p on dtip.program_id=p.id
group by p.id

Чтобы подсчитать, сколько документов, которые пользователь уже загрузил, классифицировал по программе, следующий запрос возвращает список userSession и сколько документов он загрузил ранее:

select p2.id as programId, wsc2.id as userSession, count(di2.id) as uploadedDocs
from DocumentType dt2
join DocumentInstance di2 on di2.documentType_id=dt2.id
join WebsiteCase wsc2 on di2.websiteCase_id=wsc2.id
left join Program p2 on p2.id=wsc2.program_id
group by wsc2.id

Мой вопрос: возможно ли иметь один запрос, который будет возвращаться для каждой программы, totalDocPerProgram и сколько документов уже загружено? И было бы возможно иметь что-то вроде: "Загрузите еще 2 документа для программы № 3"?

Спасибо за помощь ребята,

никола

Вот сценарий определения базы данных SQL

CREATE TABLE 'DocumentType' (
  'id' bigint(20) NOT NULL AUTO_INCREMENT,
  'description' varchar(255) DEFAULT NULL,
  'lifetime' int(11) DEFAULT NULL,
  'maxDocumentSize' int(11) DEFAULT NULL,
  PRIMARY KEY ('id')
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;


CREATE TABLE 'Program' (
  'id' bigint(20) NOT NULL AUTO_INCREMENT,
  'name' varchar(255) DEFAULT NULL,
  PRIMARY KEY ('id'),
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;


CREATE TABLE 'DataTypeForProgram' (
  'id' bigint(20) NOT NULL AUTO_INCREMENT,
  'cardinality' int(11) DEFAULT NULL,
  'dataType_id' bigint(20) DEFAULT NULL,
  'program_id' bigint(20) DEFAULT NULL,
  PRIMARY KEY ('id'),
  KEY 'FKA6CED6BFFCC6BB96' ('program_id'),
  KEY 'FKA6CED6BF17C2EE7E' ('dataType_id'),
  CONSTRAINT 'FKA6CED6BF17C2EE7E' FOREIGN KEY ('dataType_id') REFERENCES 'DataType' ('id'),
  CONSTRAINT 'FKA6CED6BFFCC6BB96' FOREIGN KEY ('program_id') REFERENCES 'Program' ('id')
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

CREATE TABLE 'WebsiteCase' (
  'id' bigint(20) NOT NULL AUTO_INCREMENT,
  'creationDate' datetime DEFAULT NULL,
  'lastUpdate' datetime DEFAULT NULL,
  'program_id' bigint(20) NOT NULL,
  PRIMARY KEY ('id'),
  KEY 'FK_Program' ('program_id'),
  CONSTRAINT 'FK_Program' FOREIGN KEY ('program_id') REFERENCES 'Program' ('id')
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

CREATE TABLE 'DocumentInstance' (
  'id' bigint(20) NOT NULL AUTO_INCREMENT,
  'url' varchar(255) DEFAULT NULL,
  'documentType_id' bigint(20) DEFAULT NULL,
  'websiteCase_id' bigint(20) DEFAULT NULL,
  PRIMARY KEY ('id'),
  KEY 'FK8BE8C2F05F1A4ADE' ('documentType_id'),
  KEY 'FK8BE8C2F05C57B856' ('websiteCase_id'),
  CONSTRAINT 'FK8BE8C2F05C57B856' FOREIGN KEY ('websiteCase_id') REFERENCES 'WebsiteCase' ('id'),
  CONSTRAINT 'FK8BE8C2F05F1A4ADE' FOREIGN KEY ('documentType_id') REFERENCES 'DocumentType' ('id')
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

CREATE TABLE 'DocumentTypeInProgram' (
  'id' bigint(20) NOT NULL AUTO_INCREMENT,
  'cardinality' int(11) DEFAULT NULL,
  'documentType_id' bigint(20) DEFAULT NULL,
  'program_id' bigint(20) DEFAULT NULL,
  PRIMARY KEY ('id'),
  KEY 'FK190E2A0A5F1A4ADE' ('documentType_id'),
  KEY 'FK190E2A0AFCC6BB96' ('program_id'),
  CONSTRAINT 'FK190E2A0AFCC6BB96' FOREIGN KEY ('program_id') REFERENCES 'Program' ('id'),
  CONSTRAINT 'FK190E2A0A5F1A4ADE' FOREIGN KEY ('documentType_id') REFERENCES 'DocumentType' ('id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SET FOREIGN_KEY_CHECKS = 0;
  • 0
    Ваш второй запрос должен быть сгруппирован по p2.id и wsc2.id.
Теги:
join

1 ответ

1
Лучший ответ

Вы можете сделать это, используя запрос, который объединяет ваши два существующих запроса. Вот так:

select a.programId, 
       a.totalDocPerProgram, 
       b.upLoadedDocs, 
       (a.totalDocPerProgram - b.upLoadedDocs) as remainingDocs, 
       b.userSession
from (
    select p.id as programId, 
           count(dt.id) as totalDocPerProgram
    from DocumentType dt
    join DocumentTypeInProgram dtip on dtip.documentType_id=dt.id
    join Program p on dtip.program_id=p.id
    group by p.id) a
join (
    select p2.id as programId, 
           wsc2.id as userSession, 
           count(di2.id) as uploadedDocs
    from DocumentType dt2
    join DocumentInstance di2 on di2.documentType_id=dt2.id
    join WebsiteCase wsc2 on di2.websiteCase_id=wsc2.id
    left join Program p2 on p2.id=wsc2.program_id
    group by p2.id, wsc2.id) b on a.ProgramId = b.ProgramId

Я не отлаживал это. Но это хорошо работает, особенно если вы включили

 where b.userSession = constant

пункт

  • 0
    Большое спасибо, это именно то, что я искал!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню