我在保存檔案資訊的資料庫上作業。資料通過幾桌蔓延,從資料File表,其中包含file_id在其他表,如存在關聯資料disk,directory,hashes,等我目前的目標是能夠根據收集的早期檔案散列資料查找重復檔案。另外的目標是能夠同時跨兩個資料庫進行查詢,因此查詢結果還將包括指示源資料庫的值,在此查詢中,這些值是虛擬??的,org_db并fnd_db作為占位符出現在結果中,我猜想,它們的存在是對解決我的問題很重要,所以我確實提到了它們的存在。
SELECT
A.file_id org_file_id,
B.file_id fnd_file_id,
AF.directory_id org_dir_id,
BF.directory_id fnd_dir_id,
AD.disk_id org_disk,
BD.disk_id fnd_disk,
1 org_db,
1 fnd_db
FROM fhash A, file AF, file BF, directory AD, directory BD
INNER JOIN fhash B ON B.data = A.data
WHERE
A.file_id <> B.file_id AND
A.file_id IN (SELECT _id FROM file WHERE directory_id IN (SELECT _id FROM directory WHERE disk_id <> 0)) AND
B.file_id IN (SELECT _id FROM file WHERE directory_id IN (SELECT _id FROM directory WHERE disk_id <> 0)) AND
A.file_id = AF._id AND
B.file_id = BF._id AND
AF.directory_id = AD._id AND
BF.directory_id = BD._id AND
ORDER BY org_file_id
| org_file_id | fnd_file_id | org_dir_id | fnd_dir_id | org_disk | fnd_disk | org_db | fnd_db |
===============================================================================================
| 97 | 118 | 5 | 8 | 2 | 3 | 1 | 1 |
| 106 | 147 | 8 | 9 | 3 | 3 | 1 | 1 |
| 106 | 175 | 8 | 10 | 3 | 3 | 1 | 1 |
| 107 | 148 | 8 | 9 | 3 | 3 | 1 | 1 |
| 107 | 176 | 8 | 10 | 3 | 3 | 1 | 1 |
| 108 | 149 | 8 | 9 | 3 | 3 | 1 | 1 |
| 108 | 177 | 8 | 10 | 3 | 3 | 1 | 1 |
| 110 | 151 | 8 | 9 | 3 | 3 | 1 | 1 |
| 110 | 179 | 8 | 10 | 3 | 3 | 1 | 1 |
...
| 118 | 97 | 8 | 5 | 3 | 2 | 1 | 1 |
| 147 | 106 | 9 | 8 | 3 | 3 | 1 | 1 |
| 148 | 107 | 9 | 8 | 3 | 3 | 1 | 1 |
| 149 | 108 | 9 | 8 | 3 | 3 | 1 | 1 |
| 151 | 110 | 9 | 8 | 3 | 3 | 1 | 1 |
| 175 | 106 | 10 | 8 | 3 | 3 | 1 | 1 |
| 176 | 107 | 10 | 8 | 3 | 3 | 1 | 1 |
| 177 | 108 | 10 | 8 | 3 | 3 | 1 | 1 |
| 179 | 110 | 10 | 8 | 3 | 3 | 1 | 1 |
我得到的結果相當不錯,可以在進一步處理后使用,但我得到的結果是我想要的兩倍。對于每一行,有一個鏡像,在表中更遠的地方,實際上下面四對列中的每一對都是先前行的副本,資料在相應的列之間切換。
我想知道的是,我是否以及如何直接從查詢中獲得正確的結果而無需進一步處理。
如果我只有兩列并且沒有磁盤、目錄和資料庫等附加因素,那么修復將很簡單
A.file_id <> B.file_id AND
到
A.file_id < B.file_id AND
另外這些行
A.file_id IN (SELECT _id FROM file WHERE directory_id IN (SELECT _id FROM directory WHERE disk_id <> 0)) AND
B.file_id IN (SELECT _id FROM file WHERE directory_id IN (SELECT _id FROM directory WHERE disk_id <> 0)) AND
只是樣本,根據他們正在改變的搜索條件,這些也可能像
A.file_id IN (SELECT _id FROM file WHERE directory_id IN (SELECT _id FROM directory WHERE disk_id = 0)) AND
B.file_id IN (SELECT _id FROM file WHERE directory_id IN (SELECT _id FROM directory WHERE disk_id = 0)) AND
或者
A.file_id IN (SELECT _id FROM file WHERE directory_id IN ([query gets ids of dir subdirs])) AND
B.file_id IN (SELECT _id FROM file WHERE directory_id IN (SELECT _id FROM directory WHERE disk_id <> 0)) AND
或者以其他方式。除了進一步修改以使其跨兩個資料庫作業之外,其余查詢幾乎保持不變。
uj5u.com熱心網友回復:
對于此示例資料,我相信使用:
GROUP BY MIN(org_file_id, fnd_file_id), MAX(org_file_id, fnd_file_id)
其中MIN()和MAX()是 SQLite 的標量函式,將消除重復項:
SELECT A.file_id org_file_id,
B.file_id fnd_file_id,
AF.directory_id org_dir_id,
BF.directory_id fnd_dir_id,
AD.disk_id org_disk,
BD.disk_id fnd_disk,
1 org_db,
1 fnd_db
FROM fhash A
INNER JOIN file AF ON A.file_id = AF._id
INNER JOIN directory AD ON AF.directory_id = AD._id
INNER JOIN fhash B ON B.data = A.data
INNER JOIN file BF ON B.file_id = BF._id
INNER JOIN directory BD ON BF.directory_id = BD._id
WHERE A.file_id <> B.file_id
AND A.file_id IN (SELECT _id FROM file WHERE directory_id IN (SELECT _id FROM directory WHERE disk_id <> 0))
AND B.file_id IN (SELECT _id FROM file WHERE directory_id IN (SELECT _id FROM directory WHERE disk_id <> 0))
GROUP BY MIN(org_file_id, fnd_file_id), MAX(org_file_id, fnd_file_id)
ORDER BY org_file_id;
我還更改為適當的顯式連接ON子句。
查看一個簡化的演示。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/339070.html
上一篇:計算IP地址屬于哪些子網
下一篇:無法識別數值“{userId}”
