2013-10-29 18 views
0

我有以下查詢:SQL多表查詢的指導

SELECT 
    _RES_COLL_EVM00012.MachineID, 
    _RES_COLL_EVM00012.Name, 
    v_GS_NETWORK_ADAPTER_CONFIGUR.IPAddress0, 
    v_GS_NETWORK_ADAPTER_CONFIGUR.DefaultIPGateway0, 
    v_GS_NETWORK_ADAPTER_CONFIGUR.TimeStamp, 
    v_GS_NETWORK_ADAPTER_CONFIGUR.RevisionID 
FROM 
    _RES_COLL_EVM00012 
    LEFT JOIN v_GS_NETWORK_ADAPTER_CONFIGUR 
    ON _RES_COLL_EVM00012.MachineID = v_GS_NETWORK_ADAPTER_CONFIGUR.ResourceID 
WHERE 
    v_GS_NETWORK_ADAPTER_CONFIGUR.IPEnabled0 = 1 
    AND v_GS_NETWORK_ADAPTER_CONFIGUR.IPAddress0 != '0.0.0.0' 
    AND v_GS_NETWORK_ADAPTER_CONFIGUR.IPAddress0 IS NOT NULL 
    AND v_GS_NETWORK_ADAPTER_CONFIGUR.DefaultIPGateway0 != '0.0.0.0' 
    AND v_GS_NETWORK_ADAPTER_CONFIGUR.DefaultIPGateway0 IS NOT NULL 
ORDER BY 
    _RES_COLL_EVM00012.Name ASC, 
    v_GS_NETWORK_ADAPTER_CONFIGUR.TimeStamp DESC, 
    v_GS_NETWORK_ADAPTER_CONFIGUR.RevisionID DESC 

它返回類似如下:

 
MachineID Name  IPAddress0  DefaultGatewayIP0   TimeStamp RevisionID 
16777323 CTNB21 192.168.17.134 192.168.17.254 9/09/2013 13:07:11 8 
16777323 CTNB21 192.168.17.143 192.168.17.254 9/09/2013 13:07:11 6 
16777585 CTNB26 192.168.16.106 192.168.16.254 28/10/2013 22:39:55 33 
16777585 CTNB26 192.168.16.116 192.168.16.254 28/10/2013 22:39:55 27 

顯然資源ID不在表v_GS_NETWORK_ADAPTER_CONFIGUR獨特。我需要做的是顯示錶_RES_COLL_EVM00012中的每一行以及來自v_GS_NETWORK_ADAPTER_CONFIGUR的每一行。

從v_GS_NETWORK_ADAPTER_CONFIGUR中選擇的行應該是具有最新TimeStamp和最大RevisionID的行。

另請注意,我實際上並不想選擇MachineID,TimeStamp或RevisionID,我剛剛這樣做是爲了更好地解釋我的請求。

一兩件事,如果行不v_GS_NETWORK_ADAPTER_CONFIGUR用火柴爲機號/資源ID存在,我仍然需要輸出的名稱,但與IPAddress0和DefaultGatewayIP0

空值,以便澄清,我想該示例結果集看起來像這個:

 
Name  IPAddress0  DefaultGatewayIP0 
CTNB21 192.168.17.134 192.168.17.254 
CTNB26 192.168.16.106 192.168.16.254 
+0

呃,以備將來參考,請注意,有'左JOIN'引用一個表,然後在'WHERE'子句中有一個**必需的**比較(...例如'v_GS_NETWORK_ADAPTER_CONFIGUR.IPEnabled0 = 1' ...)將基本上變成一個常規的'INNER JOIN'。每當你進行一個連接時,儘可能多的比較到實際的連接條件中,特別是爲了避免這種事情(請注意圍繞這種行爲有辦法,但通常不需要)。此外,是'RevisionID' _always_最終差異('最近'有效'ORDER BY')? –

回答

0

使用DENSE_RANK()OVER在下面選擇語句(PARTITION BY於RevisionId,時間戳ORDER BY於RevisionId,時間戳DESC)。

SELECT * 
FROM (SELECT _RES_COLL_EVM00012.MachineID, 
      _RES_COLL_EVM00012.Name, 
      v_GS_NETWORK_ADAPTER_CONFIGUR.IPAddress0, 
      v_GS_NETWORK_ADAPTER_CONFIGUR.DefaultIPGateway0, 
      v_GS_NETWORK_ADAPTER_CONFIGUR.TimeStamp, 
      v_GS_NETWORK_ADAPTER_CONFIGUR.RevisionID, 
      DENSE_RANK() OVER (PARTITION BY RevisionID, TimeStamp 
           ORDER BY RevisionID, TimeStamp DESC) RowID 
     FROM _RES_COLL_EVM00012 
     LEFT JOIN v_GS_NETWORK_ADAPTER_CONFIGUR 
      ON _RES_COLL_EVM00012.MachineID = v_GS_NETWORK_ADAPTER_CONFIGUR.ResourceID 
    WHERE v_GS_NETWORK_ADAPTER_CONFIGUR.IPEnabled0 = 1 
      AND v_GS_NETWORK_ADAPTER_CONFIGUR.IPAddress0 != '0.0.0.0' 
      AND v_GS_NETWORK_ADAPTER_CONFIGUR.IPAddress0 IS NOT NULL 
      AND v_GS_NETWORK_ADAPTER_CONFIGUR.DefaultIPGateway0 != '0.0.0.0' 
      AND v_GS_NETWORK_ADAPTER_CONFIGUR.DefaultIPGateway0 IS NOT NULL 
    ) XYZ 
WHERE XYZ.RowID = 1 

對於SQL Server的更多文章,請訪問SQL Server Basics

+0

請了解如何格式化您的查詢。 'DENSE_RANK()'產生'重複'等級,所以我更喜歡'ROW_NUMBER()'(授予,'RevisionId'使得這個問題不太可能)。 OP實際上並不需要你要返回的所有列(並且請始終明確列出列)。而且,'WHERE'子句中的條件將把'LEFT JOIN'變成一個普通的'INNER JOIN'。作爲個人偏好,我希望儘快執行「最近行」,以限制連接生成的潛在行數。 –

0

試試這個:

SELECT 
    --_RES_COLL_EVM00012.MachineID, 
    _RES_COLL_EVM00012.Name, 
    ISNULL(v_GS_NETWORK_ADAPTER_CONFIGUR.IPAddress0,'') as IPAddress0, 
    ISNULL(v_GS_NETWORK_ADAPTER_CONFIGUR.DefaultIPGateway0,'') as DefaultIPGateway0 
    --v_GS_NETWORK_ADAPTER_CONFIGUR.TimeStamp, 
    --v_GS_NETWORK_ADAPTER_CONFIGUR.RevisionID 
FROM 
    _RES_COLL_EVM00012 
    LEFT JOIN v_GS_NETWORK_ADAPTER_CONFIGUR 
    ON _RES_COLL_EVM00012.MachineID = v_GS_NETWORK_ADAPTER_CONFIGUR.ResourceID 
    LEFT JOIN (SELECT a.ResourceID,a.RevisionID, MAX(a.TimeStamp) as TimeStamp 
       FROM v_GS_NETWORK_ADAPTER_CONFIGUR a 
        join (SELECT ResourceID, MAX(RevisionID) as RevisionID 
         FROM v_GS_NETWORK_ADAPTER_CONFIGUR 
         GROUP BY ResourceID) b 
        ON a.ResourceID=b.ResourceID 
            GROUP BY a.ResourceID,a.RevisionID 
       )c 
    ON v_GS_NETWORK_ADAPTER_CONFIGUR.ResourceID=c.ResourceID 
     AND v_GS_NETWORK_ADAPTER_CONFIGUR.RevisionID=c.RevisionID 
     AND v_GS_NETWORK_ADAPTER_CONFIGUR.TimeStamp=c.TimeStamp 
WHERE 
    c.RevisionID IS NOT NULL 
ORDER BY 
    _RES_COLL_EVM00012.Name ASC, 
    v_GS_NETWORK_ADAPTER_CONFIGUR.TimeStamp DESC, 
    v_GS_NETWORK_ADAPTER_CONFIGUR.RevisionID DESC 
+0

#winces#...好吧,首先,這不算太壞。查找OLAP函數(具體來說,您需要'OVER()'子句)。另外,在'v_GS_NETWORK_ADAPTER_CONFIGUR'''中可能並不總是有一行**,所以'IS NOT NULL'檢查不會生效。 –