我有兩個回傳相同列的查詢。
我有兩個回傳相同列的查詢。
SELECT A.FIRST_NAME, A.MIDDLE_NAME, A.Age, B.Address
FROM table1 A INNER JOIN table2 B on A.ID = B.ID
WHERE A.FIRST_NAME IN ('123'/span>)
SELECT A.FIRST_NAME, A.MIDDLE_NAME, A.Age, B.Address
FROM table1 A INNER JOIN table2 B on A.ID = B.ID
WHERE B.Address IN ('123'/span>)
如果用戶將first_name作為輸入,則必須選擇第一個查詢的結果,如果用戶將Address作為輸入,則必須選擇第二個查詢的結果。
我試著在用戶給出名字時使用(A.FIRST_NAME = '123' or B.Address = ''),在用戶給出中間名時使用(A.FIRST_NAME = '' or B.Address = '123'),但是這使得查詢永遠運行不下去。
SELECT A.FIRST_NAME, A.MIDDLE_NAME, A.Age, B.Address
FROM table1 A INNER JOIN table2 B on A.ID = B.ID
WHERE A.FIRST_NAME IN (''/span>) OR B. 地址 IN ('123)
我希望得到專家同行的建議。
uj5u.com熱心網友回復:
典型的做法是這樣的:
SELECT a.first_name, a.middle_name, a.age, b.address
FROM table1 a
INNER JOIN table2 b on a.id = b.id
WHERE (a. id. first_name = @first_name OR @first_name IS NULL)
AND (a. 地址 = @address OR @address IS NULL)。)
這在以下情況下是可行的
DBMS將必須找到一個對所有條件都能正常作業的執行計劃。這可能是不一定很慢的全表掃描,但這也不會是閃電般的速度。
這與UNION查詢的情況不同:
SELECT a.first_name, a.middle_name, a.age, b.address
FROM table1 a
INNER JOIN table2 b on a.id = b.id
WHERE a.first_name = @first_name
UNION
SELECT a.first_name, a.middle_name, a.age, b.address
FROM table1 a
INNER JOIN table2 b on a.id = b.id
WHERE a.address = @address;
這在以下情況下是可行的
對于這個查詢,DBMS可以使用一個關于first_name的索引和另一個關于address的索引(只要你創建了這些索引),并且查詢將非常快。
這個UNION查詢畢竟只是merlely使用WHERE子句的另一種方式WHERE a.first_name = @first_name OR a.address = @address。但是通過分割查詢,你給DBMS的優化器一個提示,即它可以將此作為兩個獨立的查詢來看待,它可以使用不同的索引。如果有一個完美的優化器,這個提示就沒有必要,DBMS會自己看到這一點。我非常確定MySQL當前的優化器需要這個提示。
uj5u.com熱心網友回復:
從你下面發布的問題的查詢來看:
SELECT A.FIRST_NAME, A.MIDDLE_NAME, A.Age, B.Address FROM table1 A INNER JOIN table2 B on A.ID = B.ID WHERE A.FIRST_NAME IN ('' ) OR B.Address IN ('123')
這相當于 參考的查詢實際上將回傳所有名字不為空的記錄以及地址='123'的記錄。
我建議使用一個 if 陳述句來根據用戶的輸入執行正確的查詢。像這樣:
[EDIT]
仔細想想,你可以使用這樣一個簡化的查詢:
uj5u.com熱心網友回復: 我建議,希望能對 或者說: 第二種變體適合于四種情況:
標籤:WHERE A.FIRST_NAME IS NOT NULL OR B.Address IN ('123')/code>。考慮where子句中的排序和排序的影響是很重要的(列上的索引是一個主要因素,以及索引中的列的順序)[EDIT]。
SET @isAddress : = 1; --變數,如果用戶輸入一個地址,則被設定為'Y'表示是。如果它不是1或更大,那么用戶就輸入了一個名字。。
SET @userInput := '123'; --包含用戶輸入(地址或名)的變數。
如果@isAddress > 0 THEN
SELECT A.FIRST_NAME, A.MIDDLE_NAME, A.Age, B.Address
FROM table1 A INNER JOIN table2 B on A.ID = B.ID
WHERE B.Address = @userInput;
ELSE
SELECT A.FIRST_NAME, A.MIDDLE_NAME, A.Age, B.Address
FROM table1 A INNER JOIN table2 B on A.ID = B.ID
WHERE A.FIRST_NAME = @userInput;
END IF;
SET @isAddress : = 1; --變數,如果用戶輸入一個地址,則被設定為'Y'表示是。如果它不是1或更大,那么用戶就輸入了一個名字。。
SET @userInput := '123'; --包含用戶輸入(地址或名)的變數。
SELECT A.FIRST_NAME, A.MIDDLE_NAME, A.Age, B.Address
FROM table1 A INNER JOIN table2 B on A.ID = B.ID
WHERE (@isAddress > 0 AND B. 地址 = @userInput)
OR (@isAddress = 0 AND A. FIRSTNAME = @userInput)。)
WHERE子句進行懶惰的評估:SELECT A.FIRST_NAME, A.MIDDLE_NAME, A.Age, B.Address
FROM table1 A INNER JOIN table2 B on A.ID = B.ID
WHERE A.FIRST_NAME ='somename' or
B.地址 = '123'
SELECT A.FIRST_NAME, A.MIDDLE_NAME, A.Age, B.Address
FROM table1 A INNER JOIN table2 B on A.ID = B.ID
WHERE A.FIRST_NAME ='somenam%' AND
B.地址LIKE '12%'
= ''時,它將回傳未經過濾的集合(LIKE '%');A.FIRST_NAME = ''和B.Address != ''時,它將回傳由B.Address LIKE '12%'過濾的集合;A.FIRST_NAME != ''和B.Address = ''它將回傳由A.FIRST_NAME LIKE 'somenam%'過濾的集合;!=''時,它將回傳由兩個欄位過濾的集合(LIKE 'somevalue%')。
