2017-11-12 14 views
0

私はこれを1つのクエリとして実行しようとしていますが、サブクエリが2回しか実行されていないため、JOIN句で可能かもしれないと思っていましたが、同じ行の3倍のロールフィールド?私が考えることができる唯一の方法は、コードから一度サブクエリを実行して、このメインクエリに注入する役割と名前の値を取得することです。サブクエリの重複を減らすことは可能ですか?

SELECT id, isActive, role 
FROM accountMembers 
WHERE account=:acc 
AND isActive=true 
AND (
     (
      name > (SELECT name FROM accountMembers WHERE account=:acc AND id =:id) 
      AND role = (SELECT role FROM accountMembers WHERE account=:acc AND id =:id) 
     ) 
     OR role > (SELECT role FROM accountMembers WHERE account=:acc AND id =:id) 
) 
ORDER BY role ASC, name ASC LIMIT :lim 
+1

私はあなたが実際に成し遂げようとしていることを少し失っています。実際の希望の結果は何ですか?あなたの質問には、いくつかのサンプルデータと期待される結果を追加することで利益が得られるでしょう。 Accと:idが設定されているかどうかを表示または議論する必要があります。 – Matt

+0

@Matt order by節を追加しました。最後に受け取った 'accountMember'に基づいて結果をページ付けしています。 'name' – 0xor1

+0

https://stackoverflow.com/questions/3799193/mysql-data-best-way-to-implement-paging大丈夫ですが、あなたが' LIMIT'と 'OFFSET'を使って、 。あなたのデータセットを知らなければ、名前よりも大きい名前のアルファベット順があなたに奇妙な結果を与えるかもしれないようですが、それは例データを見ることなくすべての推測であるため、ついにわかりません。がんばろう – Matt

答えて

0

答えはただのテーブルを含めることですclausから2回目の別名を使用して2つを区別し、次のように追加の制約を追加します。

SELECT a1.id, a1.isActive, a1.role 
FROM accountMembers a1, accountMembers a2 
WHERE a1.account=:acc 
AND a1.isActive=true 
AND a2.account=:acc 
AND a2.id=:id 
AND (
     (
      a1.name > a2.name 
      AND a1.role = a2.role 
     ) 
     OR a1.role > a2.role 
) 
ORDER BY a1.role ASC, a1.name ASC LIMIT :lim 
1

MySQLはタプルの比較をサポートしています。それさえもせずに、あなたがfrom句にロジックを移動することができます

SELECT am.* 
FROM accountMembers am 
WHERE am.account = :acc and 
     am.isActive = true and 
     (am.role, am.name) > (select am2.role, am2.name 
          from accountMembers am2 
          where am2.account = :acc AND am2.id =:id 
          ); 

SELECT am.* 
FROM accountMembers am JOIN 
    ON am2.account = :acc AND am2.id =:id 

WHERE am.account = :acc and 
     am.isActive = true and 
     (am.role > am2.role or 
     am.role = am2.role and am.name > am2.name 
    ); 
関連する問題