2009-11-09 62 views
1

更新:感謝Sifu Bill的建議,我修改了SQL查詢。現在它返回正確數量的不同資產(五個)。將相關的子查詢重寫爲JOIN?

是否有可能將以下相關子查詢重寫爲JOIN?

SELECT TOP 100 PERCENT Asset_ID, work_order_id, status_id, 
downtime_hours, date_completed 
FROM dbo.mtvw_wo_reason1 
WHERE (Asset_ID IN 
(SELECT TOP 5 Asset_ID from mtvw_wo_reason1 
WHERE (Date_Completed BETWEEN '1-Oct-2009' AND '31-Oct-2009') 
GROUP BY Asset_ID 
ORDER BY SUM(Downtime_hours) DESC)) 

輸出如下:

Asset_ID work_order_id status_id downtime_hours Date_Completed 

SFM2019 2009-724 Completed .5000 2009-09-01 17:55:09.000 
SFM2019 2009-761 Completed .5000 2009-09-15 09:03:39.000 
SFM2019 2009-828 Completed 8.0000 2009-10-02 00:00:00.000 
SFM2043 2009-683 Completed .5000 2009-08-14 00:00:00.000 
SFM2043 2009-734 Completed 1.0000 2009-09-05 00:54:33.000 
SFM2043 2009-741 Completed 1.0000 2009-09-08 17:05:09.000 
SFM2043 2009-756 Completed .5000 2009-09-14 07:56:41.000 
SFM2043 2009-792 Completed 1.0000 2009-09-22 00:00:00.000 
SFM2043 2009-826 Completed 8.0000 2009-10-03 02:00:19.130 
SFM2043 2009-983 Completed 1.0000 2009-10-30 00:00:00.000 
SFM2045 2009-794 Completed 17.0000 2009-09-24 00:00:00.000 
SFM2045 2009-808 Completed 1.0000 2009-09-26 16:01:25.850 
SFM2045 2009-811 Completed 3.0000 2009-09-27 09:47:45.543 
SFM2045 2009-816 Completed 24.0000 2009-09-30 15:14:35.000 
SFM2045 2009-858 Completed 3.0000 2009-10-12 00:00:00.000 
SFM2045 2009-861 Completed .5000 2009-10-13 01:11:50.900 
SFM2045 2009-975 Completed 1.0000 2009-10-28 00:00:00.000 
SFM2045 2009-984 Completed 3.0000 2009-10-30 00:00:00.000 
SFM2088 2009-777 Completed .5000 2009-10-01 12:49:57.000 
SFM2088 2009-853 Completed .5000 2009-10-09 00:00:00.000 
SFM2088 2009-855 Completed 10.0000 2009-10-09 00:00:00.000 
SFM2200 2009-753 Completed 8.0000 2009-09-11 00:00:00.000 
SFM2200 2009-830 Completed 8.0000 2009-10-09 00:00:00.000 

在本質上查詢需要:

返回前5名的資產與 最高累計停機時間 月10月,和細分爲 這些 資產的相關工作訂單

查詢必須以不需要內部查詢中存在Date_Completed標準的方式進行重寫(這甚至可能嗎?)。使用私服比爾的回答僅得到11行(應該是23):從私服比爾的查詢

輸出:

Asset_ID work_order_id status_id downtime_hours Date_Completed 

SFM2045 2009-858 Completed 3.0000 2009-10-12 00:00:00.000 
SFM2045 2009-861 Completed .5000 2009-10-13 01:11:50.900 
SFM2045 2009-975 Completed 1.0000 2009-10-28 00:00:00.000 
SFM2045 2009-984 Completed 3.0000 2009-10-30 00:00:00.000 
SFM2200 2009-830 Completed 8.0000 2009-10-09 00:00:00.000 
SFM2043 2009-826 Completed 8.0000 2009-10-03 02:00:19.130 
SFM2043 2009-983 Completed 1.0000 2009-10-30 00:00:00.000 
SFM2088 2009-777 Completed .5000 2009-10-01 12:49:57.000 
SFM2088 2009-853 Completed .5000 2009-10-09 00:00:00.000 
SFM2088 2009-855 Completed 10.0000 2009-10-09 00:00:00.000 
SFM2019 2009-828 Completed 8.0000 2009-10-02 00:00:00.000 

謝謝你的任何見解。

+2

這是一個子查詢,但不是相關的子查詢。 – 2009-11-09 06:42:55

+0

Sifu Bill根據維基百科的相關子查詢是: 1.使用WHERE子句中外部查詢的值。 2.對於由外部查詢處理的每一行,子查詢會被評估一次。 這就是我想要完成的,你能否提供一些見解?謝謝。 – Greenhorn 2009-11-09 08:48:03

回答

2

您可以嘗試

SELECT TOP 100 PERCENT 
     Asset_ID, 
     work_order_id, 
     status_id, 
     downtime_hours 
FROM dbo.mtvw_wo_reason1 INNER JOIN 
     (
      SELECT TOP 5 
        Asset_ID 
      from mtvw_wo_reason1 
      GROUP BY Asset_ID, Date_Completed 
      HAVING Date_Completed BETWEEN '1-Oct-2009' and '31-Oct-2009' 
      ORDER BY SUM(Downtime_hours) DESC 
     ) sub ON dbo.mtvw_wo_reason1.Asset_ID = sub.Asset_ID 

編輯點評:

SELECT TOP 100 PERCENT   
     Asset_ID,   
     work_order_id,   
     status_id,   
     downtime_hours , 
     sub.Date_Completed --added 
FROM dbo.mtvw_wo_reason1 INNER JOIN   
     (    
      SELECT TOP 5         
        Asset_ID, 
        Date_Completed --added 
      from mtvw_wo_reason1     
      GROUP BY Asset_ID, Date_Completed     
      HAVING Date_Completed BETWEEN '1-Oct-2009' and '31-Oct-2009'     
      ORDER BY SUM(Downtime_hours) DESC   
     ) sub ON dbo.mtvw_wo_reason1.Asset_ID = sub.Asset_ID 
+0

這工作得很好!它需要稍作修改來指定表名。謝謝! – Greenhorn 2009-11-09 06:31:00

+0

Sifu astander,是否可以在主(外部)查詢中選擇子查詢中的Date_Completed列?謝謝你的啓發。 – Greenhorn 2009-11-09 06:47:09

+0

是的,你可以看到編輯回答 – 2009-11-09 07:09:44

1

很難猜測你打算這個查詢做。我建議,當你詢問如何解決一個沒有做你想要的查詢時,你在你的問題中包含一個關於查詢的目的是什麼的明確聲明。否則,回答的人不能從錯誤的詢問中推斷出什麼是正確的。

如果您包含表格的定義,這也很有幫助。最好的方式是用來定義表格的數據定義語言(即CREATE TABLE)。

我假設這種說法說明所需查詢結果:

「一切爲了每一個資產_ID的具有當月最累積的停機時間在十月份行。」

你可以得到,10月份期間有最停工資產就像你在子查詢正在做:

SELECT TOP 5 Asset_ID 
FROM mtvw_wo_reason1 
WHERE Date_Completed BETWEEN '2009-10-1' and '2009-10-31' 
GROUP BY Asset_ID 
ORDER BY SUM(Downtime_hours) DESC 

注意,這個查詢可以獨立運行。這是一條線索,如果你使用它作爲子查詢,它是不相關的。也就是說,它不包含對外部查詢中的值的引用。

如@astander所示,您不想將Date_Completed添加到GROUP BY子句中。您希望組是單個資產,因此每個資產可以準確獲得SUM()

但是,該表的選擇列表不包括該表中的其他列,並且該行按Asset_ID減少爲GROUP BY。所以它不會提供所有你需要的信息。因此您需要將其作爲子查詢運行。

SELECT m.Asset_ID, m.work_order_id, m.status_id, m.downtime_hours, m.Date_Completed 
FROM dbo.mtvw_wo_reason1 m 
JOIN (SELECT TOP 5 Asset_ID 
    FROM mtvw_wo_reason1 
    WHERE Date_Completed BETWEEN '2009-10-1' and '2009-10-31' 
    GROUP BY Asset_ID 
    ORDER BY SUM(Downtime_hours) DESC) sub 
    ON (m.Asset_ID = sub.Asset_ID) 
WHERE m.Date_Completed BETWEEN '2009-10-1' and '2009-10-31'; 

需要通過Date_Completed子查詢和外查詢既限制。

PS:根據我的閱讀,TOP 100 PERCENT的唯一有效用法是在最後定義VIEWORDER BY子句。

+0

Sifu Bill,謝謝您花時間回覆。我從中學到了很多東西。 SQL查詢需要返回10月份累計停機時間最長的前5個資產,併爲這些資產分配相關的工作訂單。我將編輯原始問題以提供更多細節。感謝您的耐心等待。 – Greenhorn 2009-11-14 01:06:49

+0

感謝您的問題中的額外細節。我不能想到一個簡單的方法來解決這個查詢沒有在Date_Completed的子查詢中的條件。 – 2009-11-14 02:03:50

+0

您顯示的輸出包括資產在10月以外的行。我曾認爲這不會是你想要的 - 你是否希望這些資產的所有行都在一開始的時候?無論如何,如果刪除* outer *查詢中的WHERE子句,則應該獲取這些資產的所有行。 – 2009-11-14 02:06:58