Mysql

MySQL 儲存過程在 INSERT…SELECT where in array 中使用選擇響應

  • January 20, 2022

我很確定這是一件簡單的事情,並且已經得到解答,但我似乎無法在網上找到它,或者無法正確表達它。

我有一個表 ( 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 的列表(實際上是setDISTINCT 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;

(但是,我不明白elementelementInner.

它將執行子查詢以查找 4 個 id_v 值,然後加入 ven_data 以獲取其餘列。

請提供SHOW CREATE TABLE,以便我可以建議擁有什麼索引。

引用自:https://dba.stackexchange.com/questions/181649