2017-06-13 63 views
1

我需要編寫一個非常複雜的mysql查詢,它考慮了許多條件。我會盡我所能解釋它。 我們有一張持有公司信息的表格。還有另一張表格爲這些公司設立了約會,另一張表格爲這些約會提供了各種描述。我需要結合所有3個表格,並根據用戶的搜索參數提供結果。 的表格看起來像這樣使用正則表達式的複雜SQL查詢

enter image description here

  • 「公司」表包含許多細節,如公司名稱,郵政編碼,地址,電話等

  • 「聯繫人」表中有一個'與公司ID相對應的「comp_id」單元格,名爲'entrydate'的時間戳條目(創建聯繫人時)以及預約時間設置的'appointmentdate'單元格。 它也有一個「狀態」的細胞是持有任命的說明,「contact_status」表只是ID(例如:急,低優先級等)

現在這裏是問題。 SQL是基於複雜的搜索表單創建的。由於公司內部有不同的部門,因此某些用戶對數據庫數據有不同的訪問權限......例如,必須限制郵政編碼的搜索能力,各種狀態的任命。 某些用戶可以看到一定範圍的郵政編碼,或/和只有特定的contact_statuses。由於郵政編碼太多,參數以「..和郵政編碼不以558開頭」的形式提供給我。因此,例如,以55開頭的拉鍊(一些搜索)被接受,但如果它們以558開頭,則不會。所有這些都是通過php完成的。我可以創建if/else語句來爲最終的mysql查詢創建AND或WHERE行。到目前爲止,我'熟了'這個查詢:

SELECT DISTINCT 
    a.id, a.comp_name, a.comp_zip, a.comp_addr 
    c.description as status, b.appointdate as appointement 
    FROM 
     Companies a 
     LEFT JOIN Contacts b ON b.comp_id = a.id 
     LEFT JOIN Contact_Status c ON c.id = b.status 
     WHERE a.caller_id = '45346' 
     AND (b.status NOT IN ('2', '3', '5') OR b.status IS NULL) 
     AND (a.comp_zip NOT REGEXP '50(.*)|54(.*)|55(.*)|532(.*)|668(.*)|669(.*)') 
     ORDER BY a.id 
      DESC 

但它沒有帶來正確的結果。例如,讓我們說一家公司的郵政編碼爲77554.它不會帶來這家公司,因爲正則表達式可能是錯誤的。它承認拉鍊內的55個,它忽略了這家公司。 我認爲正確的方式可能是這樣的:'^50(.*)|^54(.*)|^55(.*)....'但我不知道....我需要確保這一點。這就是爲什麼我創建這個職位。我無法在網上找到相關信息。

什麼是用reg expr檢查多個'like'值的正確方法。從什麼開始? 感謝

+0

這是個有趣的問題。你從條件'a.caller_id ='45346' AND(b.status NOT IN('2','3','5')或b.status IS NULL)得到了多少行?可以接受沒有郵政編碼過濾器的數據,然後在應用程序(而不是數據庫)上解析它? – degr

+0

另外,我有43000個郵政編碼的數據庫,我檢查了這兩個查詢 - '從zip_code中選擇SQL_NO_CACHE *,其中zip爲「50%」或zip爲「55%」或zip爲「77%」和'select SQL_NO_CACHE * from zip_code where zip regexp('^(50(。*)| 55(。*)| 77(。*))')'。 「比'查詢工作快了10倍,然後''regexp'查詢。 – degr

+0

因爲我使用jQuery數據表來顯示數據,並計算SQL行以獲得數據庫中的最終條目總數,所以我不能在SQL之後做'事情'。我需要一切都在MySQL內部。我也嘗試了'不喜歡'的解決方案,但我仍然不確定這是否正確...因爲我相信reg expr。更多我想找到一個解決方案,而不是。 300k公司中的「a.caller_id等」參數通常只能回收0-5000個條目。所以它並不可怕。它作爲一個查詢很快。順便說一句,b.status IS NULL也會帶來沒有約會的公司。 – user1033882

回答

1

你確實需要一個^()添加到REGEXP的開始,並且將這些內容包裝。試試:^(50(.*)|54(.*)|55(.*)|532(.*)|668(.*)|669(.*))

^()將確保值開始與所附的值。

爲了清楚起見,這將是您的查詢:

SELECT DISTINCT 
    a.id, a.comp_name, a.comp_zip, a.comp_addr 
    c.description as status, b.appointdate as appointement 
FROM 
    Companies a 
    LEFT JOIN Contacts b ON b.comp_id = a.id 
    LEFT JOIN Contact_Status c ON c.id = b.status 
    WHERE a.caller_id = '45346' 
    AND (b.status NOT IN ('2', '3', '5') OR b.status IS NULL) 
    AND (
    a.comp_zip NOT 
    REGEXP '^(50(.*)|54(.*)|55(.*)|532(.*)|668(.*)|669(.*))' -- changed this part 
) 
    ORDER BY a.id DESC 
+0

嗯失敗安全: (* .50)| .5(。*)| 55(。*)| 532(。*)| 668(。*)| )| 669(。*)) ,錯誤從'^(50 .....' – user1033882

+0

@ user1033882你錯過了正則表達式的單個qoutes,應該是'REGEXP'^(50(。*)| 54 (。*)| 55(。*)| 532(。*)| 668(。*)| 669(。*))'' –

+0

謝謝,你是對的...我想3h試圖解決這個搞砸了我的頭 – user1033882