![](/img/trans.png)
[英]How do I delete all the rows of a table with a recursive structure (MySQL)?
[英]MySQL: How to do a match all on linked items with our new table structure?
我們正在從用於多對多、一對多和多對一關系的單獨關系表遷移到一個可以雙向讀取的單個關系表。
我們已經轉換了幾乎所有的代碼,它似乎工作得很好,除了 GROUP BY HAVING COUNT 因為我們在新情況下確實有 2 個不同的列要檢查(而不是舊情況下的 1 個),而我們沒有知道如何正確地做到這一點。
舊表:
`news`:
id | ...
1 | ...
2 | ...
3 | ...
`news_link`:
news_id | link_module | link_id
1 | category | 1
1 | category | 3
2 | category | 1
3 | category | 3
舊查詢:
SELECT * FROM `news`
JOIN `news_link`
ON `news_link`.`news_id` = `news`.`id`
AND `news_link`.`link_id` IN (1,3)
AND `news_link`.`link_module` = 'category'
GROUP BY `news`.`id`
HAVING COUNT(DISTINCT `news_link`.`link_id`) = 2;
舊結果:
`news`:
id | ...
1 | ...
當前表:
`news`:
id | ...
1 | ...
2 | ...
3 | ...
`link`:
source_module | source_id | destination_module | destination_id
news | 1 | category | 1
news | 1 | category | 3
news | 2 | category | 1
news | 3 | category | 3
當前查詢:
SELECT * FROM `news`
WHERE `id` IN (
SELECT `link`.`source_id` AS `link_id`
FROM `link`
WHERE (`link`.`destination_module` = 'category' AND `link`.`destination_id` IN (1,3) AND `link`.`source_module` = 'news')
UNION
SELECT `link`.`destination_id` AS `link_id`
FROM `link`
WHERE (`link`.`source_module` = 'category' AND `link`.`source_id` IN (1,3) AND `link`.`destination_module` = 'news')
);
當前結果:
`news`:
id | ...
1 | ...
2 | ...
3 | ...
在這一點上,我們缺少 GROUP BY HAVING COUNT,我們確實用它來進行匹配。 例如,我們只想檢索鏈接到類別 1 和類別 3 的新聞項。如果它們只鏈接到類別 1 或類別 3,則不會。
我們已經嘗試過的:
@ids = SELECT `link`.`source_id` AS `link_id`
FROM `link`
WHERE (`link`.`destination_module` = 'category' AND `link`.`destination_id` IN (1,3) AND `link`.`source_module` = 'news')
UNION
SELECT `link`.`destination_id` AS `link_id`
FROM `link`
WHERE (`link`.`source_module` = 'category' AND `link`.`source_id` IN (1,3) AND `link`.`destination_module` = 'news';
SELECT * FROM `news`
WHERE `id` IN (@ids)
AND COUNT(@ids) = 2;
使用此解決方案,我們在檢查類別 ID 1,3 時會返回新聞 ID 1,2,3,因此我們得到 AND 3 = 2,因此我們不會返回任何項目並且進行無效比較不是比較鏈接到兩個類別的新聞項目的數量,而是比較鏈接到任一類別的新聞項目的數量。
另一個嘗試:
@ids = SELECT `link`.`source_id` AS `link_id`
FROM `link`
WHERE (`link`.`destination_module` = 'category' AND `link`.`destination_id` IN (1,3) AND `link`.`source_module` = 'news')
UNION
SELECT `link`.`destination_id` AS `link_id`
FROM `link`
WHERE (`link`.`source_module` = 'category' AND `link`.`source_id` IN (1,3) AND `link`.`destination_module` = 'news')
HAVING COUNT(DISTINCT `link`.`link_id`) = 2;
Error: Unknown column 'link.link_id' in 'having clause'
SELECT * FROM `news`
WHERE `id` IN (@ids);
有沒有人知道如何將舊查詢轉換為新表並具有與舊情況相同的結果?
我們的目標
我們的目標就像在下面的示例中一樣,擁有從鏈接表中檢索單個實體的相關模塊的代碼。
$News = $EntityManager->getRepository("News")->fetch(1);
var_dump($News->getLinks("Category"));
帶輸出:
array(2) { [0]=> object(Category)#1 (2) { ["id"]=> int(1) ["title"]=> string(4) "Test" } [1]=> object(Category)#2 (2) { ["id"]=> int(3) ["title"]=> string(6) "Test 3" } }
和
$Category = $EntityManager->getRepository("Category")->fetch(1);
var_dump($Category->getLinks("News"));
帶輸出:
array(2) { [0]=> object(News)#1 (2) { ["id"]=> int(1) ["title"]=> string(4) "News" } [1]=> object(News)#2 (2) { ["id"]=> int(2) ["title"]=> string(6) "News 2" } }
但是也:
$Form = $EntityManager->getRepository("Form")->fetch(1);
var_dump($Form->getLinks("Field"));
帶輸出:
array(2) { [0]=> object(Field)#1 (2) { ["id"]=> int(22) ["title"]=> string(8) "Field 22" } [1]=> object(Field)#2 (2) { ["id"]=> int(23) ["title"]=> string(8) "Field 23" } }
我真的不明白你想要達到的目標
SELECT * FROM `news`
JOIN `link`
ON `link`.`source_id` = `news`.`id`
AND `link`.`destination_id` IN (1,3)
AND `link`.`destination_module` = 'category'
GROUP BY `news`.`id`
HAVING COUNT(DISTINCT `link`.`destination_id`) = 2;
您的查詢幾乎相同。
您的查詢與link
不完全合乎邏輯。 source_module
= 'category' 不存在。 但是你可以從那里開始,找到想要的結果。
例如添加
link
。source_module
= '新聞'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.