Sql 如何优化或删除以下查询中的冗余
我有四张桌子Sql 如何优化或删除以下查询中的冗余,sql,sql-server,sql-server-2005,tsql,query-optimization,Sql,Sql Server,Sql Server 2005,Tsql,Query Optimization,我有四张桌子 Table1 (employee) id name -------------------- 1 a 2 b Table2 (appointment) id table1id table3id table4id sdate edate typeid ----------------------------------------------------------------------
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 */
是否有一种方法可以使用相同的条件两次减少查询次数,并只指定一次或其他更好的方法?
100102中的typeid是否会有类似的改进,在连接中使用子查询来获取所需的数字
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
您还可以尝试查看GROUPBY的HAVING子句。我想你可以做如下事情:
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)
但是,上面可能会为整个列表提取最小值和最大值,而不是每个a.id。我忘记了是否可以在max中使用分区来指定要最大化的内容,或者我是否想到了Oracle。如果没有,您可以始终使用一个子查询来为每个a.id获取最佳条目。我使用了相同的查询,而且它运行速度很快,我没有找到任何其他方法来优化它。Grrr。。。您已经定义了表别名,但不能在联接语法之外使用它们。如果您可以说明您试图回答的问题,这会有所帮助。如果您使用真实的表名和列名,而不是像d.id=b.table4id上的内部联接table4 d这样的内容,那么理解查询就会容易得多。你能解释一下你的查询应该做什么吗?我试图返回积极就业和主要就业类型的员工。每个员工可以有2-3个雇佣类型,并且可以有多个职称,晋升时可以过期,所以我想要最新记录。