MySQL 儲存過程在 INSERT…SELECT where in array 中使用選擇響應
我很確定這是一件簡單的事情,並且已經得到解答,但我似乎無法在網上找到它,或者無法正確表達它。
我有一個表 (
ven_data
) 有幾列:id_v
,lang
, 更多數據列 這裡的唯一約束是(id_v, lang)
對。我需要找到所有缺少某些語言的 ID,然後
INSERT...SELECT
從其中一種語言到所有缺少的語言。我現在所做的是,我正在獲取所有語言數量少於我需要的語言的 ID:
SELECT id_v, COUNT( 1 ) as cnt FROM `ven_data` GROUP BY id_v HAVING cnt <8 ORDER BY cnt ASC
然後我將它導出到 Notepadd++ 並刪除所有不需要的數據,製作一行 ID,如下所示:1,4,5,6
然後進行 INSERT…SELECT
INSERT INTO `ven_data`(`id_v`, `lang`, data columns) SELECT `id_v`, elementInner, data columns FROM `ven_data` WHERE `id_v` in (1,4,5,6) and `lang` = element on duplicate key update lang=elementInner;
現在我對儲存過程中的語言進行迭代沒有問題,但是如何將第一個 SQL 的結果放入
id_v
(1,4,5,6) 中?
我將選擇讓數據庫生成一個(虛擬)表,其中包含
(id_v, lang)
您希望在最後擁有的所有對。為此,您首先要獲取 all 的列表(實際上是set)
DISTINCT lang
:SELECT DISTINCT lang FROM ven_data ;
……讓我們想像它是這個
| lang | | :--- | | 輸入 | | 法語 | | 資訊科技 | | 加利福尼亞州 | | DE | | 丹麥 | | 遺傳資源 | † 中文 |
我們做同樣的事情來獲得所有的集合
DISTINCT id_v
:SELECT DISTINCT id_v FROM ven_data ;
| id_v | | ---: | | 1 | | 2 | | 3 | | 4 | | 8 | | 9 | | 11 | | 12 | | 13 |
您的
ven_data
表中應該包含的實際上是兩組的*笛卡爾積。*這是在 SQL 中通過CROSS JOIN
.這導致:
id_v | 長 ---: | :--- 1 | 在 2 | 在 3 | 在 4 | 在 8 | 在 9 | 在 11 | 在 12 | 在 13 | 在 [...] 1 | 荷蘭 2 | 荷蘭 3 | 荷蘭 4 | 荷蘭 8 | 荷蘭 9 | 荷蘭 11 | 荷蘭 12 | 荷蘭 13 | 荷蘭
你真正想要做的是
INSERT
在你的表中這個笛卡爾積中不存在的所有行。您可以通過以下方式做到這一點:
INSERT INTO ven_data (id_v, lang) SELECT id_v, lang FROM -- The whole set of (id_v, lang) pairs (SELECT DISTINCT lang FROM ven_data ) AS languages CROSS JOIN (SELECT DISTINCT id_v FROM ven_data ) AS id_list WHERE -- The pair (id_v, lang) is not already in place NOT EXISTS (SELECT 1 FROM ven_data v2 WHERE v2.id_v = id_list.id_v AND v2.lang = languages.lang ) ;
請注意,此
WHERE
條件也可以以多種方式編寫(在 MySQL 中):WHERE (id_v, lang) NOT IN (SELECT id_v, lang FROM ven_data v2 ) ;
您可以看到整個設置(以及所有步驟 1 到 1),您可以在 *此處*的dbfiddle進行實驗
注意:您不需要從儲存過程中執行此操作,也不需要使用數組。這段程式碼是相當標準的 SQL。請注意,它也適用於*PostgreSQL* 或*SQL Server*,例如。
這似乎等同於您的兩個查詢:
INSERT INTO `ven_data`(`id_v`, `lang`, data columns) SELECT `id_v`, elementInner, data columns FROM `ven_data` AS v JOIN ( SELECT id_v FROM `ven_data` GROUP BY id_v HAVING COUNT(*) < 8 ) AS x USING(id_v) WHERE `lang` = element ON duplicate key UPDATE lang = elementInner;
(但是,我不明白
element
和elementInner
.它將執行子查詢以查找 4 個 id_v 值,然後加入 ven_data 以獲取其餘列。
請提供
SHOW CREATE TABLE
,以便我可以建議擁有什麼索引。