我在數據庫中有許多表,並且我需要幫助構建快速高效的查詢。通過我迄今爲止編寫的不同查詢,結果可能不一致或較大(返回的信息比我需要的要多,因此必須稍後使用PHP來約束結果)。這是背景。如何構建mySQL查詢以查找按特定順序排序的相關信息
我們的數據庫處理老年住宅行業的線索。每個領導都有許多票據(銷售歷史),不僅給出銷售歷史,而且通知用戶下一個跟進日期(actionDate)。還有許多不同的狀態(即活動,前10名,入場等),每個潛在客戶可以分配給(儘管不是同一時間)。銷售線索的狀態是銷售過程中銷售線索發展的歷史。我們可以看到領先地位和時間。
在基礎「領導」表中,每個領導都有一個名爲「inquiryID」的自動遞增的主鍵。在大多數其他表中引用此鍵以將它們與「主導」表相關聯。這是「主角」表的結構。
TABLE: lead (~500 rows)
+-------------------+------------+-------+--------+
| Field | Type | Key | Extra |
+-------------------+------------+-------+--------+
| inquiryID | int(11) | PK | AI |
| communityID | int(3) | | |
| initialDate | date | | |
| inquirySource | tinytext | | |
| inquiryType | tinytext | | |
+-------------------+------------+-------+--------+
另一張表的標題是「leadNote」。該表處理每個銷售線索的銷售日記帳。基本上,銷售人員會在撰寫票據的日期(銷售人員),票據本身(註釋),跟進主管(actionCounselor)的日期以及他們將跟進的日期(actionDate)。
TABLE: leadNote (~15000 rows)
+-------------------+------------+-------+--------+
| Field | Type | Key | Extra |
+-------------------+------------+-------+--------+
| inquiryNoteID | int(11) | PK | AI |
| inquiryID | int(11) | FK | |
| date | date | | |
| salesCounselor | tinytext | | |
| note | text | | |
| actionCounselor | int(5) | | |
+-------------------+------------+-------+--------+
我將參考的最終表格標題爲「leadStatusHistory」。這個表格處理這個領先地位的歷史。領導可以有許多不同的狀態,但不能同時進行。我們希望能夠跟蹤潛在客戶的狀態和時間。潛在客戶將擁有狀態(leadStatus),狀態被分配給他們的日期(statusDate)以及誰將狀態分配給他們(作者)以及其他收集的數據。
TABLE: leadStatusHistory (~1200 rows)
+-------------------+-------------+-------+--------+
| Field | Type | Key | Extra |
+-------------------+-------------+-------+--------+
| historyID | int(11) | PK | AI |
| inquiryID | int(11) | FK | |
| leadStatus | tintytext | | |
| date | datetime | | |
| communityID | int(3) | | |
| timestamp | timestamp | | |
+-------------------+-------------+-------+--------+
我的目標是能夠運行,返回inquiryID,actionCounselor,actionDate和當前leadStatus查詢。正如我前面所說,我嘗試過的許多不同的查詢帶來了不同的結果。我想收集這個列表有兩種方式。 1)找到下一個聯繫日期小於或等於今天的所有潛在客戶(這是今天跟進的潛在客戶名單)。 2)找到與當前某個leadStatus相匹配的所有線索(即,查找當前狀態爲「移入」的所有線索。
這就是我如何訂購表格以獲取我的信息查找 1)查找inquiryID,actionCounselor(最近創建的「leadNote」行或「date」最大的actionCounselor列中的值),actionDate(最近創建的「leadNote」的actionDate列中的值)最大的行或「日期」)和leadStatus(最近創建的「leadStatusHistory」行中的leadStatus列中的值或最大的「時間戳」)WHERE actionDate(最近一次的actionDate列中的值創建「leadNote」行或「最大」的日期)小於或等於今天。
2)查找詢問ID,actionCounselor(最近創建的「leadNote」行或「date」最大的actionCounselor列中的值),actionDate(最近創建的「leadNote」的actionDate列中的值)最大的行或「日期」)和leadStatus(最近創建的「leadStatusHistory」行中的leadStatus列中的值或最大的「時間戳」)WHERE leadStatus(最近創建的leadStatus列中的值「leadStatusHistory」行或最大的「時間戳」)等於「移入」。
下面是一些當前和過去的查詢和我的評論的例子,他們有什麼問題。
查詢#1:
SELECT
tt.inquiryID,
tt.actionDate,
tt.date,
tt.actionCounselor,
(SELECT
leadstatushistory.leadstatus
FROM
leadstatushistory
WHERE
leadstatushistory.inquiryID = tt.inquiryID AND leadstatushistory.historyID = (SELECT
MAX(leadstatushistory.historyID) as historyID
FROM
leadstatushistory
WHERE
inquiryID = tt.inquiryID)) AS leadStatus
FROM
leadnote tt
INNER JOIN
(SELECT
inquiryID,
MAX(inquiryNoteID) as inquiryNoteID,
MAX(leadnote.actionDate) AS actionDate
FROM
leadnote
GROUP BY inquiryID) groupedtt ON tt.inquiryID = groupedtt.inquiryID AND tt.inquiryNoteID = groupedtt.inquiryNoteID
WHERE
tt.actionDate <= '2012-08-27' AND tt.actionDate != '0000-00-00' AND (SELECT
leadstatushistory.leadstatus
FROM
leadstatushistory
WHERE
leadstatushistory.inquiryID = tt.inquiryID AND leadstatushistory.historyID =
(SELECT
MAX(leadstatushistory.historyID) as historyID
FROM
leadstatushistory
WHERE
inquiryID = tt.inquiryID)) != 'Resident' AND tt.communityID = 4
GROUP BY tt.inquiryID
評論:給我我所需要的列,但有過抱怨,現在,然後在「actionDate」欄將不會反映的最近創建的日期leadNote行,有時leadStatus是錯誤的。例如,leadStatusHistory表的max(historyID)不一定是我們想要查找的最新狀態。有時候,我們的員工會回過頭去填補缺少的leadStatus過去的線索。這將創建一個新的leadStatusHistory行,並創建一個新的自動增量historyID。在這種情況下,最近的(或最大的歷史ID)沒有最大的「leadStatusHistory.date」,因爲用戶輸入的日期是過去的日期(填寫過去的信息以便我們的歷史記錄是準確的)。我們在將筆記輸入leadNote表格以查找以前的筆記時也遇到同樣的問題。新的自動增量查詢註釋ID不一定匹配具有最大「tt.date」的行。
查詢#2:
SELECT
maxDate.inquiryID, maxDate.date, maxDate.actionDate, maxDate.actionCounselor
FROM
(SELECT
*
FROM
leadnote
ORDER BY date DESC , type ASC, inquiryNoteID DESC) as maxDate
LEFT JOIN
staff ON maxDate.actionCounselor = staff.staffID
WHERE
maxDate.communityID = 4
GROUP BY inquiryID
評論:給我我所需要的列,但它也發現所有線索的信息。這浪費寶貴的時間並使響應變慢。然後,我必須使用PHP來限制數據,以僅顯示具有< = today的actionDate和不是「0000-00-00」的日期的數據,或者限制數據僅顯示帶leadStatus的數據「移入」。同樣,這確實給了我正在尋找的結果,但速度很慢。此外,如果我在子查詢中添加查詢「WHERE date < = [today] AND date!='0000-00-00'」,它會更改結果以使它們不準確,然後我仍然必須使用PHP來約束結果只顯示那些我正在尋找的狀態。
通過查看上述信息,是否有人有任何想法如何更好地構建我的查詢,以便我可以快速找到我正在尋找的確切信息。或者有沒有辦法改變表格的結構或關係以獲得我期待的結果。請,任何幫助表示讚賞。
您可以發佈一些EXPLAIN輸出嗎? –
您的文本正文中提到了不會出現在您的表結構中的列leadNote.actionDate,leadStatusHistory.statusDate和leadStatusHistory.author。那是一個疏忽?你還應該閱讀關於獲取[groupwise maxima](http://dev.mysql.com/doc/en/example-maximum-column-group-row.html)。 – eggyal