[英]Select user having qualifying data on multiple rows in the wp_usermeta table
我試圖找到具有所有四個限定值的user_id
每個值都在數據庫表的不同行中。
我正在查詢的表是wp_usermeta
:
Field Type Null Key Default Extra
---------------------------------------------------------------------------
umeta_id bigint(20) unsigned PRI auto_increment
user_id bigint(20) unsigned IND 0
meta_key varchar(255) Yes IND NULL
meta_value longtext Yes NULL
我寫了一個 MySQL 查詢,但它似乎不起作用,因為結果是空的。
$result = mysql_query(
"SELECT user_id
FROM wp_usermeta
WHERE
(meta_key = 'first_name' AND meta_value = '$us_name') AND
(meta_key = 'yearofpassing' AND meta_value = '$us_yearselect') AND
(meta_key = 'u_city' AND meta_value = '$us_reg') AND
(meta_key = 'us_course' AND meta_value = '$us_course')"
);
如何返回與所有四行相關的user_id
?
我會使用這個查詢:
SELECT
user_id
FROM
wp_usermeta
WHERE
(meta_key = 'first_name' AND meta_value = '$us_name') OR
(meta_key = 'yearofpassing' AND meta_value = '$us_yearselect') OR
(meta_key = 'u_city' AND meta_value = '$us_reg') OR
(meta_key = 'us_course' AND meta_value = '$us_course')
GROUP BY
user_id
HAVING
COUNT(DISTINCT meta_key)=4
這將選擇滿足所有四個條件的所有user_id
。
@fthiella 的解決方案非常優雅。
如果將來您想要顯示的不僅僅是user_id
您可以使用連接,並且在一行中可能包含您需要的所有數據。
如果要使用AND
條件,並且條件在表中的多行中,則可以使用JOINS
示例:
SELECT `w_name`.`user_id`
FROM `wp_usermeta` as `w_name`
JOIN `wp_usermeta` as `w_year` ON `w_name`.`user_id`=`w_year`.`user_id`
AND `w_name`.`meta_key` = 'first_name'
AND `w_year`.`meta_key` = 'yearofpassing'
JOIN `wp_usermeta` as `w_city` ON `w_name`.`user_id`=`w_city`.user_id
AND `w_city`.`meta_key` = 'u_city'
JOIN `wp_usermeta` as `w_course` ON `w_name`.`user_id`=`w_course`.`user_id`
AND `w_course`.`meta_key` = 'us_course'
WHERE
`w_name`.`meta_value` = '$us_name' AND
`w_year`.meta_value = '$us_yearselect' AND
`w_city`.`meta_value` = '$us_reg' AND
`w_course`.`meta_value` = '$us_course'
其他:推薦使用prepared statement,因為mysql_*
函數不是SQL注入保存,會被棄用。 如果你想盡可能少地改變你的代碼,你可以使用mysqli_
函數: http : mysqli_
推薦:
使用此表中的索引。 user_id
強烈推薦使用和索引,並推薦使用meta_key
和meta_value
,以便更快地運行查詢。
解釋:
如果您使用AND
“連接”一行的條件。 所以如果你想要多行的 AND 條件,首先你必須從多行創建一行,像這樣。
測試:表數據:
PRIMARY INDEX
int varchar(255) varchar(255)
/ \ |
+---------+---------------+-----------+
| user_id | meta_key | meta_value|
+---------+---------------+-----------+
| 1 | first_name | Kovge |
+---------+---------------+-----------+
| 1 | yearofpassing | 2012 |
+---------+---------------+-----------+
| 1 | u_city | GaPa |
+---------+---------------+-----------+
| 1 | us_course | PHP |
+---------+---------------+-----------+
使用$us_name='Kovge'
$us_yearselect='2012'
$us_reg='GaPa'
, $us_course='PHP'
:
+---------+
| user_id |
+---------+
| 1 |
+---------+
所以它應該有效。
如果要同時應用這兩個屬性,也可以使用“AND”而不是“OR”。
select * from tickets where (assigned_to='1') and (status='open') order by created_at desc;
您正在查詢一個表,該表被設計為我所看到的稱為“統一內容模型”(UCM) 的東西。 當首選最大數據靈活性時選擇此表結構。 這種結構的缺點是效率受到影響,表通常會因數據過於臃腫而受到影響,並且查詢表通常涉及使用稱為“樞軸”的技術的聚合函數。
以下是如何使用數據透視表執行查詢:( db-fiddle 演示)
SELECT user_id
FROM wp_usermeta
GROUP BY user_id
HAVING MAX(IF(meta_key = 'first_name', meta_value, NULL)) = 'mangesh'
AND MAX(IF(meta_key = 'yearofpassing', meta_value, NULL)) = '2013'
AND MAX(IF(meta_key = 'u_city', meta_value, NULL)) = 'n/a'
AND MAX(IF(meta_key = 'us_course', meta_value, NULL)) = 'programming'
實際上,整個表按user_id
列分組。 在這樣做的過程中,形成了一種臨時的一對多關系。 換句話說,每個相應的user_id
將有一個或多個行的數據(非線性,非平面),可以被 MySQL 的聚合函數(例如MAX()
)查詢。
HAVING 子句是過濾器邏輯必須在 GROUP BY 之后的地方(WHERE 過濾發生在 GROUP BY 之前)。 在“數據集群”中,您可以通過檢查其meta_key
來隔離數據。 當您找到與meta_key
匹配的meta_key
,您將使用它的meta_value
,否則您分配一個不同的默認值。 在聚合中的所有行都被IF
處理后,您知道您要查找的行是非 NULL 值——這是通過調用MAX()
訪問的。 使用此最大值與您要過濾的實際值進行比較。 根據需要重復此過濾器以滿足您的業務邏輯。
我還應該聲明,您沒有使用安全編碼實踐。 mysql_query()
目前已被棄用,無論出於何種原因都不應該存在於任何當前運行的代碼中。 我建議您使用 mysqli 的面向對象語法,並為安全性/穩定性實現帶有綁定參數的准備好的語句。
$sql = "SELECT user_id
FROM wp_usermeta
GROUP BY user_id
HAVING MAX(IF(meta_key = 'first_name', meta_value, NULL)) = ?
AND MAX(IF(meta_key = 'yearofpassing', meta_value, NULL)) = ?
AND MAX(IF(meta_key = 'u_city', meta_value, NULL)) = ?
AND MAX(IF(meta_key = 'us_course', meta_value, NULL)) = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ssss', $us_name, $us_yearselect, $us_reg, $us_course);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($user_id);
$stmt->fetch();
echo $user_id;
您有互相排斥的條件 - 如果meta_key是'first_name',它也不能是'yearofpassing'。 很可能你需要你的AND是OR的:
$result = mysql_query("SELECT user_id FROM wp_usermeta
WHERE (meta_key = 'first_name' AND meta_value = '$us_name')
OR (meta_key = 'yearofpassing' AND meta_value = '$us_yearselect')
OR (meta_key = 'u_city' AND meta_value = '$us_reg')
OR (meta_key = 'us_course' AND meta_value = '$us_course')")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.