Упрощение MySQL Query для удаления нескольких выборок в операторе Where

0

У меня есть следующий запрос, чтобы подсчитать количество разрешений на работу и задаться вопросом, можно ли упростить удаление большого количества выборок, чтобы найти статус разрешения. Это выполняется на веб-странице, поэтому мне нужно свести количество данных и получить их до минимума

SELECT SUM(IF(tbl_permit_status.status_id = (SELECT tbl_status.status_id FROM tbl_status WHERE tbl_status.status = 'Requested'), 1, 0)) AS requested,
   SUM(IF(tbl_permit_status.status_id = (SELECT tbl_status.status_id FROM tbl_status WHERE tbl_status.status = 'Approved'), 1, 0)) AS approved,
   SUM(IF(tbl_permit_status.status_id = (SELECT tbl_status.status_id FROM tbl_status WHERE tbl_status.status = 'Issued'), 1, 0)) AS issued,
   SUM(IF(tbl_permit_status.status_id = (SELECT tbl_status.status_id FROM tbl_status WHERE tbl_status.status = 'Signed On'), 1, 0)) AS signed_on,
   SUM(IF(tbl_permit_status.status_id = (SELECT tbl_status.status_id FROM tbl_status WHERE tbl_status.status = 'Suspended'), 1, 0)) AS suspended,
   SUM(IF(tbl_permit_status.status_id = (SELECT tbl_status.status_id FROM tbl_status WHERE tbl_status.status = 'Cleared'), 1, 0)) AS cleared,
   SUM(IF(tbl_permit_status.status_id = (SELECT tbl_status.status_id FROM tbl_status WHERE tbl_status.status = 'Cancelled'), 1, 0)) AS cancelled,
   COUNT(*) AS total
FROM tbl_permit_status
  INNER JOIN tbl_permit_number
ON tbl_permit_status.permit_id = tbl_permit_number.permit_id
  INNER JOIN tbl_permit_client
ON tbl_permit_status.permit_id = tbl_permit_client.permit_id 
  • 0
    Вы уверены, что это дает вам правильный счет? Вы присоединяетесь только на permit_id . Из их названий я понимаю, что три таблицы являются подробными таблицами разрешений. Поэтому я думаю, что для одного permit_id вас может быть две записи tbl_permit_status , три записи tbl_permit_number и четыре записи tbl_permit_client . Вы бы посчитали 2 x 3 x 4 = 24 записи, 12 для одного статуса, 12 для другого. Это действительно предназначено?
Теги:

2 ответа

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

Просто присоединитесь к таблице состояния:

SELECT 
  SUM(s.status = 'Requested') AS requested,
  SUM(s.status = 'Approved') AS approved,
  SUM(s.status = 'Issued') AS issued,
  SUM(s.status = 'Signed On') AS signed_on,
  SUM(s.status = 'Suspended') AS suspended,
  SUM(s.status = 'Cleared') AS cleared,
  SUM(s.status = 'Cancelled') AS cancelled,
  COUNT(*) AS total
FROM tbl_permit_status ps
INNER JOIN tbl_permit_number pm ON ps.permit_id = pm.permit_id
INNER JOIN tbl_permit_client pc ON ps.permit_id = pc.permit_id 
INNER JOIN tbl_status s ON ps.status_id = s.status_id

Как вы можете видеть, вы даже можете просто использовать выражения SUM (т.е. Не нужно IF), потому что true равно 1, а false - 0 в MySQL.

(Если tbl_permit_status.status_id может быть нулевым, а затем левая, присоединитесь к таблице состояний вместо внутреннего соединения, чтобы получить правильное общее количество.)

  • 0
    Ваше решение не является правильным, потому что, если INNER JOIN имеют отношение 1 к N, это вернет больше записей, и SUM будет слишком большим. Вы рассматриваете случай, когда STATUS-ID равен NULL (отношение от 0 до 1), но вы забыли рассмотреть отношение 1-N
  • 0
    @schlebe: на самом деле я этого не сделал. Я только что написал запрос, дающий тот же результат, что и запрос OP. Пожалуйста, обратите внимание, что я писал комментарий к запросу, именно тогда, когда вы писали свой ответ на мой ответ :-) Если бы мы хотели подсчитать только статусы, нам бы не пришлось присоединяться к tbl_permit_number и tbl_permit_client . Остается неясным, к какому результату фактически применяется OP и как связаны таблицы (особенно: permit_id уникален в одной из таблиц или нет?).
0

Я думаю, что эту команду SELECT можно свести к

SELECT s.*
      ,COUNT(*) AS total
FROM
  (
  SELECT SUM(IF(status = 'Requested' ,1,0)) as requested
        ,SUM(IF(status = 'Approved'  ,1,0)) as approved
        ,...

    FROM tbl_permit_status
  ) as s
  INNER JOIN tbl_permit_number as n
    ON n.permit_id = s.permit_id
  INNER JOIN tbl_permit_client as c
    ON c.permit_id = s.permit_id 

Примечание. Я не эксперт MySql, но я знаю Oracle и TrasactSQL. Я надеюсь, что MySql принимает встроенный SQL (я думаю, что это стандартный SQL) и что "как" после представления/таблицы принимаются (что принято на SqlServer, но не на Oracle).

Ещё вопросы

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