簡體   English   中英

選擇在 wp_usermeta 表中的多行上具有合格數據的用戶

[英]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_keymeta_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM