2014-12-04 26 views
0

我想知道如果有人能夠關注我正在執行的查詢,我無法完全想到最好的方式來做到這一點。加入表格然後在Max Date上過濾

我需要來自聯繫人表的電子郵件,名字和姓氏以及來自熱線表的熱線ID和最後動作。我想存儲在熱線表格只顯示行「標誌」列篩選其中的值是1。我已經通過這個查詢實現這一點:

select Email, FirstName, Surname, HotlineID, LastAction 
from Hotline 
left join contact on contact.companyid=hotline.CompanyID 
       and contact.ContactID=hotline.ContactID 
where 
hotline.Flag = 1 

現在有點我不能這樣做。在動作表中有3列'HotlineID''Comment''日期',動作表中的HotlineID鏈接到熱線表中的HotlineID。可以爲每條熱線添加多條評論,並將他們發佈的日期記錄在日期列中。

從第一個查詢返回的行中,我想進一步篩選出最大日期(最後記錄的註釋)小於當前日期48小時後的任何行。我在Visual Studio中使用'addwithvalue'來填充日期變量,但出於測試目的,我使用'2014-12-04'

我想出了這個,失敗了。但我不確定爲什麼?

Select Email, FirstName, Surname, hotline.HotlineID, LastAction 
from Hotline 
left join Contact on Contact.CompanyID=Hotline.CompanyID 
       and Contact.ContactID=Hotline.ContactID 
inner join Actions on actions.HotlineID=hotline.HotlineID 
where hotline.flag=1 and CONVERT(VARCHAR(25), Max(Date), 126) LIKE '2014-12-03%' 

我正在使用SQL Server。

+0

你使用的是SQL Server嗎? – Rhumborl 2014-12-04 16:04:17

+1

這是什麼DBMS? SQL Server? – 2014-12-04 16:04:26

+0

Both,sorry是SQL server – rjn239 2014-12-04 16:06:26

回答

1

MAX()是一組行的集合功能。如果它出現在選擇列表中,它的使用會將你的普通查詢轉換成一個聚合查詢,這看起來並不是你想要的。顯然,SQL Server根本不會在where子句中接受它。

好像你想是這樣的,而不是:

SELECT 
    Contact.Email, 
    Contact.FirstName, 
    Contact.Surname, 
    recent.HotlineID, 
    Hotline.Action 
FROM 
    (SELECT HotlineID, MAX([Date]) as maxDate 
    FROM Hotline 
    GROUP BY HotlineID) recent 
    INNER JOIN Hotline 
    ON recent.HotlineId = Hotline.HotlineId 
    LEFT JOIN Contact 
    ON Hotline.HotlineId = Contact.HotlineId 
WHERE 
    datediff(hour, recent.maxDate, GetDate()) < 48 
    AND Hotline.Flag = 1 

也許你想要把WHERE子句中的子查詢中。由此產生的查詢將有一個稍微不同於上面的意思,我不確定你真的想要什麼。

+0

感謝您的回覆,這非常符合我試圖實現的目標。我改變了select中的一些列,因爲它們引用了錯誤的東西(可能來自我的解釋)。當我執行:SELECT HotlineID,MAX([日期])作爲maxDate 從操作 WHEREiffiff(小時,日期,GetDate())> 48 GROUP BY HotlineID在它自己的Actions表中返回所有日期比今天少了48小時,太棒了!但是當我在整個查詢中運行它時,它會通過熱線在最後一個動作是今天? – rjn239 2014-12-04 17:22:35

+0

嗨我可以問一下上面的一些發展。我剛剛意識到(我想)發生了什麼事。再次引用我之前評論中提到的Select語句。這就是說,查看動作表中的HotlineID的所有記錄,如果存在比當前時間早48小時的可用記錄,則返回該記錄。我想要的是Select語句查看Actions表中的HotlineID的所有記錄,如果LAST記錄的日期比今天早48小時,則返回它,如果不是這樣的話。任何想法如何適應?謝謝。 – rjn239 2014-12-05 09:54:09

+0

好吧...所以我只是注意到我把「小時,日期,GetDate()))> 48」,而不是「小時,maxDate,GetDate()))> 48」改變這個maxDate拋出錯誤'無效列名'maxDate'',我相信這是因爲你不能在WHERE子句中引用Alias',但可能是錯誤的? – rjn239 2014-12-05 10:22:13

0

你可以試試這個

Select Email, FirstName, Surname, hotline.HotlineID, LastAction 
from Hotline 
left join Contact on Contact.CompanyID=Hotline.CompanyID 
       and Contact.ContactID=Hotline.ContactID 
inner join Actions on actions.HotlineID=hotline.HotlineID 
where hotline.flag=1 
    and CONVERT(VARCHAR(25), Max(Date), 126) < CONVERT(VARCHAR(25), GetDate() - 2, 126) 
+0

感謝您的快速回復!我在執行該錯誤時遇到此錯誤:Msg 147,Level 15,State 1,Line 7 聚合可能不會出現在WHERE子句中,除非它位於包含在HAVING子句或選擇列表中的子查詢中,而列聚合是一個外部參考。 – rjn239 2014-12-04 16:22:05

+0

您必須在選擇列表中添加Max(日期)也 – HaveNoDisplayName 2014-12-04 16:37:13

0

約翰的查詢在派生表中使用熱線表而不是您的動作表之外是很好的。

SELECT Email, FirstName, Surname, HotlineID, LastAction 
FROM Hotline h 
INNER JOIN 
(SELECT hotlineID, max(date) as Date FROM actions a1 GROUP BY hotlineID) a 
ON h.hotlineID = a.hotlineID 
LEFT JOIN contact c 
ON c.companyid=h.CompanyID and c.ContactID=h.ContactID   
WHERE 
hotline.Flag = 1 
and datediff(hour,[Date],getdate()) > 48 
+0

需要進行一次修改,特別是'h.Flag = 1'而不是'hotline.Flag = 1',否則這個修改就會發生並返回與John的查詢相同的行!謝謝:D – rjn239 2014-12-05 16:32:47