查询连接和优化

时间:2012-02-23 08:32:33

标签: sql sql-server

我有一个表格INFO,其设计就像这样

id - bigint
Name - varchar2
refid - bigint
status - int
ExpDate - datetime
  • 状态值可以是0,1,2,3,4
  • refid也是我们将要使用的其他表的外键
  

我想编写一个查询,其中所有记录都应来自此表,状态为0,1,2,3,但expdate只有7条最新记录的状态为4。

我无法弄清楚如何在T-SQL中实现这一目标。

请帮帮我或给我建议,以便我可以开始写作。

到目前为止我已经写过了

SELECT * 
FROM INFO 
WHERE STATUS IN (0,1,2,3) AND 
      REFID IN (SELECT REFID FROM REFTABLE WHERE REFCHAIN='BMW')

SELECT TOP 7
FROM INFO 
WHERE STATUS=4 AND 
      REFID IN(SELECT REFID FROM REFTABLE WHERE REFCHAIN='BMW') 
ORDER BY EXPDATE DESC

我需要加入他们???如何...建议以及查询

(SELECT REFID FROM REFTABLE WHERE REFCHAIN='BMW') 

有两次如何优化它,谢谢..

4 个答案:

答案 0 :(得分:4)

将你当前的两个查询联合起来(你需要一个派生表来获得TOP)

SELECT ...
FROM INFO 
WHERE STATUS IN (0,1,2,3) AND 
      REFID IN (SELECT REFID FROM REFTABLE WHERE REFCHAIN='BMW')
UNION ALL
SELECT ...
FROM 
    (
    SELECT TOP 7 ...
    FROM INFO 
    WHERE STATUS=4 AND 
          REFID IN(SELECT REFID FROM REFTABLE WHERE REFCHAIN='BMW') 
    ORDER BY EXPDATE DESC
    ) T

你可以变得更有魅力,但可能效率不高:

SELECT *
FROM
    (
    SELECT ...,
       ROW_NUMBER() OVER (ORDER BY EXPDATE DESC) AS rn
    FROM INFO 
    WHERE REFID IN (SELECT REFID FROM REFTABLE WHERE REFCHAIN='BMW')
    ) T
WHERE
    rn <= 7 OR STATUS <= 4

答案 1 :(得分:1)

您想要优化此功能,还是只想删除重复记录。

如果要删除重复记录,可以尝试使用UNION-

SELECT * FROM INFO 
INNER JOIN REFTABLE ON INFO.refId = REFTABLE.Id
WHERE REFCHAIN = 'BMW' AND INFO.status IN (0,1,2,3)
UNION
SELECT FROM 
    (
       SELECT TOP 7 FROM INFO 
       INNER JOIN REFTABLE ON INFO.refId = REFTABLE.Id
       WHERE INFO.status=4 AND REFCHAIN='BMW'
       ORDER BY EXPDATE DESC
    ) T

答案 2 :(得分:0)

对于你的reftable中最新的7个值你可以使用这个查询 -

select * from REFTABLE where REFID not in( select top (select count(*)-7 from info) REFID from REFTABLE )

如果你可以发布表格结构会更好。

答案 3 :(得分:0)

关于UNION的gbn和Pavanred答案解决了你的问题“如何加入这个结果”。 如果需要优化,您可以为select的结果创建临时表。然后查询只执行一次。

但是... 我认为查询太简单了,不能以这种方式优化它。

反正:

SELECT REFID 
INTO #temp1 
FROM REFTABLE WHERE REFCHAIN='BMW'

然后在这两个查询中使用它:

WHERE REFID IN (SELECT REFID FROM #temp1)

或者那样

SELECT ...
FROM INFO inf
INNER JOIN #temp1 t ON inf.REFID = t.REFID
...