2013-04-08 143 views
2

從每個id中返回一個項目而不是表中的所有其他項目的最佳方式是什麼?目前,下面的查詢將返回所有的廠家消除SQL查詢中的重複項

SELECT m.name 
FROM `default_ps_products` p 
INNER JOIN `default_ps_products_manufacturers` m ON p.manufacturer_id = m.id 
+0

所以你想'default_ps_products'中的每一行'default_ps_products_manufacturers'?你對某一行有偏好嗎?或者它可以是隨機的嗎? – Andomar 2013-04-08 19:49:19

+0

@Andomar可以隨機只想要所有制造商 – 2013-04-08 19:50:50

回答

2

我已經在我的查詢中使用DISTINCT值解決了我的問題一個不好的做法。這可能是因爲你的SELECT語句有問題,或者你的數據結構沒有被標準化。

在你的情況下,我會用這個(假設default_ps_products_manufacturers有唯一的記錄)。

SELECT m.id, m.name 
FROM default_ps_products_manufacturers m 
WHERE EXISTS (SELECT 1 FROM default_ps_products p WHERE p.manufacturer_id = m.id) 

,或者在同等查詢:

SELECT m.id, m.name 
FROM default_ps_products_manufacturers m 
WHERE m.id IN (SELECT p.manufacturer_id FROM default_ps_products p) 

的唯一的事情 - 所有可能的查詢之間,最好是選擇一個與更好的執行計劃。這可能取決於您的數據庫的供應商和/或物理結構,統計數據等。

我認爲在大多數情況下,EXISTS會更好。

0

有我能想到的4點主要的方式來刪除重複的行 方法1 刪除所有行比最小的比最大的ROWID值更大或更小。例如

delete from tableName a where rowid> (select min(rowid) from tableName b where a.key=b.key and a.key2=b.key2) 

方法2 通常更快,但你必須重新創建所有索引,約束和事後觸發..
拉都作爲不同的新表然後刪除第一個表,新表重命名爲舊錶名 例子。

create table t1 as select distinct * from t2; drop table t1; rename t2 to t1; 

方法3 刪除其中存在基於ROWID uing。例如

delete from tableName a where exists(select 'x' from tableName b where a.key1=b.key1 and a.key2=b.key2 and b.rowid >a.rowid) Note if nulls are on column use nvl on column name.  

方法4 收集第一行的每個密鑰值和在該組未刪除行。

SELECT DISTINCT m.name, m.id 
FROM `default_ps_products` p 
INNER JOIN `default_ps_products_manufacturers` m ON p.manufacturer_id = m.id 
ORDER BY m.name 
+0

我不想刪除它們我只是不想在結果中顯示它們 – 2013-04-08 20:04:06

+0

'nvl'是Oracle,但問題在於MySQL – Andomar 2013-04-08 20:28:15

0

使用DISTINCT往往是:例如

delete from tableName a where rowid not in(select min(rowid) from tableName b group by key1, key2) 

注意,您不必使用NVL的方法4