![](/img/trans.png)
[英]What is the difference between many-to-many cross table and one-to-one cross table
[英]MySQL convert many-to-many table into one-to-one
我有一個通過連接 2 個表創建的表,現在這兩列看起來像具有many-to-many
關系。 我想將其轉換為one-to-one
關系含義,兩列中的值都必須是unique
。 這是一個示例設置;
create table Test(id1 integer, id2 integer);
insert into Test(id1, id2) values(1, 10);
insert into Test(id1, id2) values(1, 20);
insert into Test(id1, id2) values(2, 10);
insert into Test(id1, id2) values(2, 20);
select * from Test;
id1 | id2 |
---|---|
1 | 10 |
1 | 20 |
2 | 10 |
2 | 20 |
我想將上表轉換為如下內容;
tbl1
id1 | id2 |
---|---|
1 | 10 |
2 | 20 |
或者
tbl2
id1 | id2 |
---|---|
1 | 20 |
2 | 10 |
如何編寫 SQL 查詢將test
表轉換為tbl1
或tbl2
?
這將取出我在其他答案的評論中提到的獨特價值。
SELECT a.id1, b.id2
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY id1) AS RowNum FROM (SELECT DISTINCT id1 FROM test) x
) AS a,
(
SELECT *, ROW_NUMBER() OVER (ORDER BY id2) AS RowNum FROM (SELECT DISTINCT id2 FROM test) x
) AS b
WHERE a.RowNum = b.RowNum
如果有什么我誤解了,請告訴我。
好的。 要強制表具有唯一列,您只需在表上添加唯一索引。 (隨時更改為索引上更好的名稱)。
CREATE UNIQUE INDEX my_index_name_1 ON test(id1);
CREATE UNIQUE INDEX my_index_name_2 ON test(id2);
然后索引將不允許任何重復。 (創建上面的索引時不能有任何重復。)
但是....如果您可以完全控制數據庫,那么如果只有 1 對 1 的關系,擁有這種類型的表似乎有點奇怪。 然后你可以在兩個主表上添加一個字段。
如果 id 來自表 'Table1' 和 'Table2' 你可以在 Table1 中有一個名為 table2_id 的字段並指向 table2 中的行。 在 Table2 中,您可以有一個名為 table1_id 的字段,它將指向 table1。 然后你可以跳過這個表,所有的搜索都會更快。 但當然,這可能是有原因的。 反正就是想提一下...
我一開始誤解了這個問題,所以這是我的新答案。 據我了解,您想刪除行,所以剩下的唯一行是唯一的,刪除哪些行並不重要? 如果是這樣,此解決方案將起作用:
DELETE test
FROM test
JOIN (
SELECT * FROM (
SELECT t.id1, t.id2, (SELECT MAX(id2) FROM test WHERE id1 = t.id1) AS maxId2
from test t
) AS r
WHERE r.id2 != maxId2
) d
ON d.id1 = test.id1 AND d.id2 = test.id2;
此查詢將刪除除具有最高 id2 的行之外的所有行。 請在運行之前對其進行測試並進行備份,我當然已經在我身邊測試過它,但仍然如此。
關系數據庫在設計上不推薦/允許多對多關系。 但是,對於這個特定的要求,下面的代碼應該更接近你想要的。 代碼在dbfiddle
create table tb11(id1 integer, id2 integer);
create table tb12(id1 integer, id2 integer);
INSERT INTO tb11
SELECT id1, id2 FROM
(SELECT
id1,
id2,
RANK() OVER (PARTITION BY id2 ORDER BY id1 ASC) as rnk
FROM
Test) t1 where t1.rnk = 1;
INSERT INTO tb12
SELECT id1, id2 FROM
(SELECT
id1,
id2,
RANK() OVER (PARTITION BY id2 ORDER BY id1 ASC) as rnk
FROM
Test) t2 where t2.rnk = 2;
SELECT * FROM tb11;
SELECT * FROM tb12;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.