0

次の表があります。

CREATE TABLE `relations` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `relationcode` varchar(25) DEFAULT NULL,
  `email_address` varchar(100) DEFAULT NULL,
  `firstname` varchar(100) DEFAULT NULL,
  `latname` varchar(100) DEFAULT NULL,
  `last_contact_date` varchar(25) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

このテーブルには重複があります。これらは、relationcode と email_address がまったく同じ関係です。彼らはそこに2回、または10回もいる可能性があります。すべてのレコードの ID を選択するクエリが必要ですが、そこに複数回あるものは除外します。それらのレコードのうち、最新の last_contact_id のみを持つレコードのみを選択したいと思います。

私はMysqlよりもOracleに興味があります。Oracleでは、次のようにすることができます。

select * from (
    select row_number () over (partition by relationcode order by to_date(last_contact_date,'dd-mm-yyyy')) rank, 
           id, 
           relationcode,  
           email_address , 
           last_contact_date
    from RELATIONS)
where rank = 1

しかし、このクエリを MySql で動作するように変更する方法がわかりません。MySQl の単一のクエリで同じことを実行できるかどうかはわかりません。何か案は?

4

2 に答える 2

3

これを行う通常の方法は、最新のレコードを取得し、それをテーブルに対して結合するサブクエリです。

SELECT id, relationcode, email_address, firstname, latname, last_contact_date
FROM RELATIONS
INNER JOIN
(
    SELECT relationcode, email_address, MAX(last_contact_date) AS latest_contact_date
    FROM RELATIONS
    GROUP BY relationcode, email_address
) Sub1
ON RELATIONS.relationcode = Sub1.relationcode
AND RELATIONS.email_address = Sub1.email_address
AND RELATIONS.last_contact_date = Sub1.latest_contact_date

変数を使用して、Oracle クエリが使用するランクの種類を手動で生成することができます。ちょっと面倒だけど!

SELECT id, relationcode, email_address, firstname, latname, last_contact_date
FROM
(
    SELECT id, relationcode, email_address, firstname, latname, last_contact_date, @seq:=IF(@relationcode = relationcode AND @email_address = email_address, @seq + 1, 1) AS seq, @relationcode := relationcode, @email_address := email_address
    (
        SELECT id, relationcode, email_address, firstname, latname, last_contact_date
        FROM RELATIONS
        CROSS JOIN (SELECT @seq:=0, @relationcode := '', @email_address :='') Sub1
        ORDER BY relationcode, email_address, last_contact_date DESC
    ) Sub2
) Sub3
WHERE seq = 1

これは、サブクエリを使用して変数を初期化します。リレーション コードと電子メール アドレスが前の行と同じ場合はシーケンス番号が追加され、そうでない場合は 1 にリセットされてフィールドに格納されます。次に、外側の選択でシーケンス番号が (変数名ではなくフィールドとして) チェックされ、1 の場合にのみレコードが返されます。

これを複数のサブクエリとして行ったことに注意してください。一部はわかりやすくするためですが、MySQL が実行する順序を強制しようとするためでもあります。問題を引き起こす可能性のあるものの実行を MySQL が指示する方法には、いくつかの問題が考えられます。彼らは私のためにやったことはありませんが、サブクエリで注文を強制したいと思います.

于 2014-05-30T09:46:42.573 に答える