Консолидация COUNT-запроса - PullRequest
1 голос
/ 17 ноября 2009

У меня есть страница, на которой я запускаю исходный запрос SQL, чтобы получить список субъектов, затем я повторяю цикл над этим запросом и запускаю два дополнительных запроса для каждой записи, возвращенной из исходного запроса субъектов (я, случается, делаю это в ColdFusion, но не уверен, что это действительно имеет значение). Эти два дополнительных запроса выполняют СЧЕТЫ для этого конкретного субъекта, а затем выводят результаты (выведите имя субъекта, а затем два числа для этого субъекта). Я пытался улучшить производительность этой страницы и хотел узнать, смогу ли я как-нибудь объединить это в один запрос.

Начальный запрос:

   SELECT subject_ID, subject_name
   FROM Subjects
   ORDER BY subject_name

Запросы внутри цикла исходного запроса:

   SELECT COUNT(test_ID) as priority_count
   FROM Test_Queue
   WHERE priority_flag = 1 AND subject_ID = #SubjectQuery.subject_ID#

   SELECT COUNT(test_ID) as locked_count
   FROM Test_Queue
   WHERE locked = 1 AND subject_ID = #SubjectQuery.subject_ID#

Предложения о том, как их можно оптимизировать? БД - это MS SQL 2008. Спасибо.

Ответы [ 4 ]

3 голосов
/ 17 ноября 2009
SELECT 
    subject_ID, 
    subject_name,
    priority_count = (select count(test_id) from test_queue where priority_flag = 1),
    locked_count = (select count(test_id) from test_queue where locked = 1)
FROM Subjects
ORDER BY subject_name

или, если в подсчетах предполагается включить subject_id (только предположение), тогда

SELECT 
    s.subject_ID, 
    s.subject_name,
    priority_count = (select count(test_id) from test_queue t where priority_flag = 1 and t.subject_id = s.subject_id),
    locked_count = (select count(test_id) from test_queue t where locked = 1 and t.subject_id = s.subject_id)
FROM Subjects s
ORDER BY subject_name
2 голосов
/ 17 ноября 2009

Это должно сделать это, предполагая, что столбец соединения из субъектов в test_queue является правильным, вы не указали, какой столбец в test_queue ссылается на субъекты

select
    subjects.subject_id
   ,subjects.subject_name
   ,sum(case when test_queue.priority_flag=1 THEN 1 ELSE 0 END) as priority_count
   ,sum(case when test_queue.locked=1 THEN 1 ELSE 0 END) as locked_count
  from
    subjects
    left join test_queue
       on subjects.subject_id=test_queue.subject_id
  group by subjects.subject_id, subjects.subject_name
  order by subjects.subject_name
1 голос
/ 17 ноября 2009

Я возьму пунт, который Test_Queue.Subject_ID = Subjects.Subject_ID

SELECT s.subject_ID, s.subject_name, COUNT(t1.*) as priority_count, COUNT(t2.*) as locked_count
  FROM Subjects s
  LEFT OUTER JOIN Test_Queue t1
    ON s.Subject_ID = t1.Subject_ID
   AND t1.priority_flag = 1
  LEFT OUTER JOIN Test_Queue t2
    ON s.Subject_ID = t2.Subject_ID
   AND t2.locked = 1
 GROUP by s.subject_ID, s.subject_name
 ORDER BY s.subject_name
1 голос
/ 17 ноября 2009

как то так? (вам может потребоваться привести к INT, если priority_flag или locked имеет тип, который не нравится SUM)

SELECT
  subject_ID
, subject_name
, SUM(priority_flag) AS priority_count
, SUM(locked) AS locked_count
FROM Subjects s, Test_Queue tq
GROUP BY subject_ID, subject_name
ORDER BY subject_name
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...