簡體   English   中英

MySQL 5.5中多表更新的正確語法

[英]Proper syntax for multiple table update in MySQL 5.5

我正在嘗試驗證用於在MySQL 5.5中執行多表更新的正確語法。 我有兩個表,第一個表的結構如下:

| *post_id* | lat | long |

其中post_id是唯一標識符。 第二個表是Wordpress postmeta表:

| *meta_id* | post_id | meta_key | meta_value |

其中meta_id是唯一標識符。 來自第一個表的Post_ID與第二個表匹配。 第二個表中的一些meta_keys包括list-latlist-long

我希望用第二個表中的相應值更新第一個表中的long值,其中long是0.000000而lat不是0.000000。 以下選擇語句標識130行:

SELECT * FROM bch_postmeta
JOIN bch_coords ON bch_coords.post_id = bch_postmeta.post_id
WHERE bch_coords.long = 0.000000 
AND bch_coords.lat <> 0.000000 AND bch_postmeta.meta_key = 'list-long'

這是預期的。 如果我嘗試一個簡單的UPDATE並模擬它,我將再次影響130行:

UPDATE bch_coords
SET bch_coords.long = 0.0 
WHERE bch_coords.long = 0.000000 AND bch_coords.lat <> 0.000000

但是,一旦我嘗試合並第二個表,查詢就會停止工作。 以下兩個查詢都影響0行。 第二個當然是我希望進行的更新。

UPDATE bch_coords, bch_postmeta
SET bch_coords.long = 0.0 
WHERE bch_coords.long = 0.000000 AND bch_coords.lat <> 0.000000

UPDATE bch_coords, bch_postmeta
SET bch_coords.long = bch_postmeta.meta_value
WHERE bch_coords.post_id = bch_postmeta.post_id AND bch_postmeta.meta_key = 'list-long'
AND bch_coords.long = 0.000000 AND bch_coords.lat <> 0.000000

我沒有使用過ANSI聯接,因為它們由於某種原因(無論在什么時候還是個謎)在UPDATE使用時都會導致查詢失敗。

誰能確切說明我在這里做錯了什么?

我在下面創建了一個SQLFiddle降價:

SQL小提琴

MySQL 5.5模式設置

CREATE TABLE bch_coords
    (`post_id` int, `lat` numeric, `long` numeric, UNIQUE(post_id))
;

INSERT INTO bch_coords
    (`post_id`, `lat`, `long`)
VALUES
    (1, 15.986132, 136.82515),
    (2, 0.000000, 0.000000),
    (3, -15.23850, 0.000000),
    (4, 136.32067, 0.000000),
    (5, -87.123567, 56.12396)
;


CREATE TABLE bch_postmeta
    (`meta_id` int, `post_id` int, `meta_key` varchar(13), `meta_value` varchar(15), UNIQUE(meta_id))
;

INSERT INTO bch_postmeta
    (`meta_id`, `post_id`, `meta_key`, `meta_value`)
VALUES
    (1, 1, '''list-lat''', '15.986132'),
    (2, 1, '''list-long''', '136.82515'),
    (3, 1, '''country''', '''Switzerland'''),
    (4, 1, '''state''', '''Valais'''),
    (5, 2, '''list-lat''', '0.000000'),
    (6, 2, '''list-long''', '0.000000'),
    (7, 2, '''country''', '''Australia'''),
    (8, 3, '''list-lat''', '-15.00'),
    (9, 3, '''list-long''', '173.62198'),
    (10, 3, '''country''', '''USA'''),
    (11, 4, '''list-lat''', '136.32067'),
    (12, 4, '''list-long''', '5.123997'),
    (13, 5, '''list-lat''', '-88.125'),
    (14, 5, '''list-long''', '56.12396')
;

所以,我有一個看起來像這樣的數據集...

SELECT * FROM bch_coords;
+---------+------+------+
| post_id | lat  | long |
+---------+------+------+
|       1 |   16 |  137 |
|       2 |    0 |    0 |
|       3 |  -15 |    0 |
|       4 |  136 |    0 |
|       5 |  -87 |   56 |
+---------+------+------+

SELECT * FROM bch_postmeta;
+---------+---------+-------------+---------------+
| meta_id | post_id | meta_key    | meta_value    |
+---------+---------+-------------+---------------+
|       1 |       1 | 'list-lat'  | 15.986132     |
|       2 |       1 | 'list-long' | 136.82515     |
|       3 |       1 | 'country'   | 'Switzerland' |
|       4 |       1 | 'state'     | 'Valais'      |
|       5 |       2 | 'list-lat'  | 0.000000      |
|       6 |       2 | 'list-long' | 0.000000      |
|       7 |       2 | 'country'   | 'Australia'   |
|       8 |       3 | 'list-lat'  | -15.00        |
|       9 |       3 | 'list-long' | 173.62198     |
|      10 |       3 | 'country'   | 'USA'         |
|      11 |       4 | 'list-lat'  | 136.32067     |
|      12 |       4 | 'list-long' | 5.123997      |
|      13 |       5 | 'list-lat'  | -88.125       |
|      14 |       5 | 'list-long' | 56.12396      |
+---------+---------+-------------+---------------+

...並且在更新之后,我想要一個看起來像這樣的數據集...

SELECT * FROM bch_coords;
+---------+------+------+
| post_id | lat  | long |
+---------+------+------+
|       1 |   16 |  137 |
|       2 |    0 |    0 |
|       3 |  -15 |  173 |
|       4 |  136 |  5.1 |
|       5 |  -87 |   56 |
+---------+------+------+

嘗試這個:

UPDATE bch_coords
SET bch_coords.long = (SELECT bch_postmeta.meta_value 
                       FROM bch_postmeta 
                       WHERE bch_postmeta.post_id = bch_coords.post_id
                       AND bch_postmeta.meta_key = 'list-long'
                       LIMIT 1)
WHERE bch_coords.long = 0.000000 
AND bch_coords.lat <> 0.000000

或這個:

UPDATE bch_coords 
INNER JOIN bch_postmeta ON (bch_coords.post_id = bch_postmeta.post_id AND bch_postmeta.meta_key = 'list-long')
SET bch_coords.long = bch_postmeta.meta_value
WHERE bch_coords.long = 0.000000 
AND bch_coords.lat <> 0.000000 

順便說一句,它比您的實際問題更有趣,但有時會忘記,如果精心構建視圖,就可以使用它來更新其基礎表。 考慮以下:

SELECT * FROM bch_postmeta;
+---------+---------+-------------+---------------+
| meta_id | post_id | meta_key    | meta_value    |
+---------+---------+-------------+---------------+
|       1 |       1 | 'list-lat'  | 15.986132     |
|       2 |       1 | 'list-long' | 136.82515     |
|       3 |       1 | 'country'   | 'Switzerland' |
|       4 |       1 | 'state'     | 'Valais'      |
|       5 |       2 | 'list-lat'  | 0.000000      |
|       6 |       2 | 'list-long' | 0.000000      |
|       7 |       2 | 'country'   | 'Australia'   |
|       8 |       3 | 'list-lat'  | -15.00        |
|       9 |       3 | 'list-long' | 173.62198     |
|      10 |       3 | 'country'   | 'USA'         |
|      11 |       4 | 'list-lat'  | 136.32067     |
|      12 |       4 | 'list-long' | 5.123997      |
|      13 |       5 | 'list-lat'  | -88.125       |
|      14 |       5 | 'list-long' | 56.12396      |
+---------+---------+-------------+---------------+

CREATE VIEW v_bch_postmeta AS
SELECT a.post_id
     , a.meta_value list_lat
     , b.meta_value list_long
     , c.meta_value country
     , d.meta_value state
  FROM bch_postmeta a
  LEFT
  JOIN bch_postmeta b
    ON b.post_id = a.post_id
   AND b.meta_key = "'list-long'"
  LEFT
  JOIN bch_postmeta c
    ON c.post_id = a.post_id
   AND c.meta_key = "'country'"
  LEFT
  JOIN bch_postmeta d
    ON d.post_id = a.post_id
   AND d.meta_key = "'state'"
 WHERE a.meta_key = "'list-lat'";

Query OK, 0 rows affected (0.01 sec)

SELECT * FROM v_bch_postmeta;
+---------+-----------+-----------+---------------+----------+
| post_id | list_lat  | list_long | country       | state    |
+---------+-----------+-----------+---------------+----------+
|       1 | 15.986132 | 136.82515 | 'Switzerland' | 'Valais' |
|       2 | 0.000000  | 0.000000  | 'Australia'   | NULL     |
|       3 | -15.00    | 173.62198 | 'USA'         | NULL     |
|       4 | 136.32067 | 5.123997  | NULL          | NULL     |
|       5 | -88.125   | 56.12396  | NULL          | NULL     |
+---------+-----------+-----------+---------------+----------+

UPDATE v_bch_postmeta SET list_lat = 1.0 WHERE post_id = 2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

SELECT * FROM bch_postmeta;
+---------+---------+-------------+---------------+
| meta_id | post_id | meta_key    | meta_value    |
+---------+---------+-------------+---------------+
|       1 |       1 | 'list-lat'  | 15.986132     |
|       2 |       1 | 'list-long' | 136.82515     |
|       3 |       1 | 'country'   | 'Switzerland' |
|       4 |       1 | 'state'     | 'Valais'      |
|       5 |       2 | 'list-lat'  | 1.0           |
|       6 |       2 | 'list-long' | 0.000000      |
|       7 |       2 | 'country'   | 'Australia'   |
|       8 |       3 | 'list-lat'  | -15.00        |
|       9 |       3 | 'list-long' | 173.62198     |
|      10 |       3 | 'country'   | 'USA'         |
|      11 |       4 | 'list-lat'  | 136.32067     |
|      12 |       4 | 'list-long' | 5.123997      |
|      13 |       5 | 'list-lat'  | -88.125       |
|      14 |       5 | 'list-long' | 56.12396      |
+---------+---------+-------------+---------------+

這不適用於視圖中的NULL值

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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