2016-12-08 5 views
2

は、ここに私のテーブル構造である:MySQLは条件でレコードを削除する方法を

CREATE TABLE `order` 
    (`order_id` int, `order_status_id` int, `ip` varchar(11), `date_added` datetime) 
; 

INSERT INTO `order` 
    (`order_id`, `order_status_id`, `ip`, `date_added`) 
VALUES 
    (1, 0, '192.168.1.1', '2016-12-07 00:00:00'), 
    (2, 0, '192.168.1.1', '2016-12-07 00:00:00'), 
    (3, 0, '192.168.1.1', '2016-12-07 00:00:00'), 
    (4, 0, '192.168.1.1', '2016-12-07 00:00:00'), 
    (5, 1, '192.168.1.1', '2016-12-07 00:00:00'), 

    (6, 0, '192.168.1.2', '2016-12-08 00:00:00'), 
    (7, 0, '192.168.1.2', '2016-12-08 00:00:00'), 
    (8, 0, '192.168.1.2', '2016-12-08 00:00:00'), 
    (9, 0, '192.168.1.2', '2016-12-08 00:00:00'), 
    (10, 1, '192.168.1.2', '2016-12-08 00:00:00'), 

    (11, 0, '192.168.1.3', '2016-12-09 00:00:00'), 
    (12, 0, '192.168.1.3', '2016-12-09 00:00:00'), 
    (13, 0, '192.168.1.3', '2016-12-09 00:00:00'), 
    (14, 0, '192.168.1.3', '2016-12-09 00:00:00'), 
    (15, 0, '192.168.1.3', '2016-12-09 00:00:00'); 

http://sqlfiddle.com/#!9/20c0f

は、私は、SQL消去を期待ORDER_IDがあるレコードを除くすべてのレコード:5、10、15

説明:条件付きのorder_status_id = 0のレコードを消去したいと思います。

a)レコードの1つ(同じip/date_addedのorder_idからの)に順序がある場合_status_id = 1とし、order_status_id = 0(同じip/date_addedから)のすべてのレコードを消去します。私の例では、レコード1-4と6-9は削除する必要があります。

b)order_id = 1(すべてのレコードにorder_status_id = 0がある)と同じip/date_addedのレコードがない場合は、order_idが最も高いレコードを1つ残ります(他のすべてが削除されます)。私の例では、レコード11-14を削除する必要があります。

+0

。 **何を試しましたか?** – tadman

+0

このコードは、条件Aの動作)ではないB)(Oに )OO をDATE_ADDED IPで ここORDER_STATUS_ID = 1 基、o- order' 'から をDATE_ADDED、IPを選択order' O に参加'から oを削除します。 ip = oo.ipおよびo.date_added = oo.date_added o.order_status_id = 0; – tester

+0

これは条件b)では部分的に機能しますが、a)は削除されませんn1 FROM 'order' n1、' order' n2 WHERE n1.order_id> n2.order_id AND n1.order_status_id = '0' AND n2.order_status_id = '0' AND n1.ip = n2.ip 日(n1.date_added)=日(n2.date_added) – tester

答えて

1

SQL DEMO

まず、あなたはあなたの状態を分ける必要があります。あなたは

-- first filter 
SELECT `ip`, `date_added` 
FROM `order` 
GROUP BY `ip`, `date_added` 
HAVING MAX(`order_status_id`) = 1; 

-- second filter  
SELECT `ip`, `date_added` 
FROM `order` 
GROUP BY `ip`, `date_added` 
HAVING MAX(`order_status_id`) = 0; 

まずあなたは、誰もが最初のフィルタに一致するだけ削除1

DELETE o 
FROM `order` o 
INNER JOIN (
    SELECT `ip`, `date_added` 
    FROM `order` 
    GROUP BY `ip`, `date_added` 
    HAVING MAX(`order_status_id`) = 1 
) filter 
    ON o.`ip` = filter.`ip` 
AND o.`date_added` = filter.`date_added` 
WHERE o.`order_status_id` = 0; 

第二のものを左に意味order_status_id = 0持つものが 削除削除 を削除order_status_id {0,1}{ip,date}を持っています誰もが第二のフィルターに合っているが、誰も彼よりも高いIDは持っていないままにしておいてください。かなり具体的な要件です

DELETE o1 
FROM `order` o1 
INNER JOIN (
    SELECT `ip`, `date_added` 
    FROM `order` 
    GROUP BY `ip`, `date_added` 
    HAVING MAX(`order_status_id`) = 0 
) filter 
    ON o1.`ip` = filter.`ip` 
AND o1.`date_added` = filter.`date_added` 
LEFT JOIN `order` o2 
    ON o1.`order_id` < o2.`order_id` 
WHERE o2.`ip` IS NOT NULL; 

OUTPUT enter image description here

+0

それは動作します!非常に大きなマスターありがとう!爆発のためにありがとう! – tester

+0

もう一度私を助けてくださいますか?私の実際のテーブルの日付形式は時間分と秒(2016-12-08 12:23:53)ですので、h:m:sを除いてY-m-dを比較する必要があります。私はあなたのSQLリクエストを次のように採用しようとしましたが( 'on節'のerronのために動作しません): – tester

+0

delete o FROM 'order' o INNER JOIN( SELECT' ip'、Day( 'date_added') ip' 'BY order' GROUP' FROM、月( 'date_added') 、日(' date_added')、月( 'date_added') HAVING MAX(' order_status_id')= 1 )o.' ON をフィルタリングip' = filter.'ip' 日(o.'date_added')=日(filter.'date_added') と月(o.'date_added')=月(filter.'date_added') O。 'order_status_id' = 0; – tester

関連する問題