Как оптимизировать или удалить избыточность из следующего запроса - PullRequest
0 голосов
/ 27 января 2010

у меня 4 стола

Table1 (employee)
id          name
--------------------
1           a
2           b

Table2 (appointment)
id    table1id    table3id    table4id   sdate    edate     typeid
-----------------------------------------------------------------------------------
1       1              1          1      1/1/09    NULL       100
2       2              2          1      1/1/09    NULL       101


Table3 (title)
id      name
---------------
1       worker1
2       worker2
3       Assistant
4       Manager

Table4 (Department names)
id      name
-------------------
1       Logistics
2       ABC
3       XYZ

Type
id       name
----------------
100      w (primary)
101      e (secondary)
102      r (other-primary)
103      t (.....)
104      y (....)

Во избежание дублирования я пишу запрос как

Select id, name, title, dept
FROM table1 a
INNER JOIN table2 b ON a.id = b.table1id
INNER JOIN table3 c ON b.table3id = c.id
INNER JOIN table4 d ON d.id = b.table4id
WHERE typeid =
        (
           SELECT min(type_id) /* i want primary type appointments */
           FROM table2
           WHERE sdate < getdate() and (edate > getdate() or edate IS NULL)
           AND sdate = (select max(sdate) from table2 where table1id = a.id)
           AND typeid in (100, 102)
        )
AND b.sdate < getdate() and (b.edate > getdate() or b.edate IS NULL)
AND b.sdate = (select max(sdate) from table2 where table1id = a.id)

/* last two i have to repeat again to remove dupes */

Есть ли способ, которым я могу сократить использование одного и того же условия в два раза и запросить его, указав только один раз или каким-либо другим лучшим способом? И ввод в (100, 102)

Ответы [ 2 ]

0 голосов
/ 01 февраля 2010

Я использовал тот же запрос, и он работает быстро, я не нашел другого способа оптимизировать его

0 голосов
/ 27 января 2010

Было бы что-то вроде улучшения, используя подзапрос в соединении, чтобы получить нужные числа?

Select id, name, title, dept
FROM table1 a
INNER JOIN table2 b ON a.id = b.table1id
INNER JOIN table3 c ON b.table3id = c.id
INNER JOIN table4 d ON d.id = b.table4id
INNER JOIN (select max(sdate) from table2 group by table1id) new1 ON new1.table1id = a.id
WHERE typeid =
    (
       SELECT min(type_id) /* i want primary type appointments */
       FROM table2
       WHERE sdate < getdate() and (edate > getdate() or edate IS NULL)
       AND sdate = (select max(sdate) from table2 where table1id = a.id)
       AND typeid in (100, 102)
    )
AND b.sdate < getdate() and (b.edate > getdate() or b.edate IS NULL)
AND b.sdate = new1.sdate

Вы также можете попытаться найти предложение HAVING в GROUP BY. Я думаю, что вы сможете сделать что-то вроде:

Select id, name, title, dept
FROM table1 a
INNER JOIN table2 b ON a.id = b.table1id
INNER JOIN table3 c ON b.table3id = c.id
INNER JOIN table4 d ON d.id = b.table4id
WHERE b.sdate < getdate() and (b.edate > getdate() or b.edate IS NULL)
AND typeid in (100, 102)
GROUP BY id, name, title, dept
HAVING b.sdate = max(sdate)
  AND typeid = min(type_id)

Однако вышеприведенное может потянуть min и max для всего списка, а не для каждого a.id. Я забыл, можете ли вы использовать раздел в параметре max, чтобы указать, на что максить больше, или я думаю об Oracle там. Если нет, вы всегда можете использовать подзапрос, который получает лучшую запись для каждого a.id.

...