MySQL CASE“それ以外の場合”前提条件が真のときに実行されている-私は何が欠けていますか?

StackOverflow https://stackoverflow.com/questions/1620973

  •  06-07-2019
  •  | 
  •  

質問

私が使用しているサードパーティのシステムにより、データが重複しているテーブルがあります。モデルはEAVメソッドを使用しているため、これを「正しい」フィルター処理する方法はありません。方法で、私はデータをビューに集約しています-これはデータ収集の問題であることは知っていますが、このシステムを通過して既存のデータとフォームを破壊するよりも、ディスプレイ側で修正する方が簡単です。 2つのフィールドのいずれかをチェックして、一方または両方が入力されているかどうかを確認する必要がありますが、1つだけを選択します(そうしないと、名前が「John」ではなく「John、John」と2回表示されます)。関連部分のコードは次のとおりです。

group_concat(
(
  case when (`s`.`fieldid` = 2) then `s`.`data` 
  else
    case when (`s`.`fieldid` = 35) then `s`.`data` 
    else NULL end 
  end
) separator ','),_utf8'') as first_name

fieldid 2とfieldid 35の両方が入力された場合、フィールドID = 35の値ではなく、フィールドID = 2の値を返すだけであると予想されます。 。しかし、それをつかんで、else句の内側にある場合でもケースを実行していますか?

このコードを修正して、fieldid = 2またはfieldid = 35のいずれかを与えることができますが、両方を一緒にグロブしないようにして、名前が重複するようにしますか?

編集

表の構造は次のとおりです。

table: subscribers_data
subscriberid (int)   fieldid (int)   data (text)    

E-A-V構造を使用しているため、サンプルレコードは次のようになります。

subscriberid          fieldid         data
1                     2               John
1                     3               Smith
1                     35              John
1                     36              Smith

fieldid 2および35がカスタムフィールド" First Name"である(別のテーブルで定義)およびfieldid 3および36は「姓」です。

私が使用している完全なビューは次のとおりです。

select `ls`.`subscriberid` AS `id`,
left(`l`.`name`,(locate(_utf8'_',`l`.`name`) - 1)) AS `user_id`,
ifnull(group_concat((
    case when (`s`.`fieldid` = 2) then `s`.`data` 
    when (`s`.`fieldid` = 35) then `s`.`data` 
    else NULL end) separator ','),_utf8'') AS `first_name`,
ifnull(group_concat((
    case when (`s`.`fieldid` = 3) then `s`.`data` 
    when (`s`.`fieldid` = 36) then `s`.`data` 
    else NULL end) separator ','),_utf8'') AS `last_name`,
ifnull(`ls`.`emailaddress`,_utf8'') AS `email_address`,
ifnull(group_concat((
    case when (`s`.`fieldid` = 81) then `s`.`data` 
    else NULL end) separator ','),_utf8'') AS `mobile_phone`,
ifnull(group_concat((
    case when (`s`.`fieldid` = 100) then `s`.`data` 
    else NULL end) separator ','),_utf8'') AS `sms_only` 
from ((`list_subscribers` `ls` 
join `lists` `l` on((`ls`.`listid` = `l`.`listid`))) 
left join `subscribers_data` `s` on((`ls`.`subscriberid` = `s`.`subscriberid`))) 
where (left(`l`.`name`,(locate(_utf8'_',`l`.`name`) - 1)) regexp _utf8'[[:digit:]]+') 
group by `ls`.`subscriberid`,`l`.`name`,`ls`.`emailaddress`

ビューはRuby on Railsアプリケーションのモデルとして使用されているため、「user_id」を偽造するために創造的なハッキングを使用しています。 Railsが期待するもの(新しいユーザーを追加するときにフロントエンドRailsアプリが生成する数値IDを使用して、Listsテーブルのフィールドlist.nameに名前を付けるため、ビューをRailsのように見えるようにするためにこの数値のみを抽出しています) -convention database table)

役に立ちましたか?

解決

group_concat()の内部には、実行中のコンテキストを表示する方法がありません。したがって、1つのグループに2つの行があり、1つは fieldid = 2 で、もう1つは fieldid = 35 で、次のようになります。

  • fieldid = 2 で行を処理しています...
    • s.fieldid = 2 はtrueで、 s.data
    • を返します
  • fieldid = 35 で行を処理しています...
    • s.fieldid = 2 はfalseです。 else 部分を試してください
    • s.fieldid = 35 はtrueで、 s.data
    • を返します

これは、なぜ "John"なのかを説明しています;複数回返されました。修正する唯一の方法は、 group_concat()の外部で別のクエリを実行することです。

編集:

本当にこのようにする必要があるので、代わりに次のようなものを使用してください:

SELECT ...
   min(CASE WHEN s.fieldid IN (2,35) THEN s.data ELSE NULL END) AS first_name
...

別の方法として、2つの値が異なることができない場合は group_concat(DISTINCT ...)を実行できます(そうでない場合は、たとえば「John、Johny」を取得します)。 first_name / last_nameに2つの値があるのはなぜですか?

他のヒント

私はmysqlの男ではありませんが、sqlサーバーのcaseステートメントでは、最初の「else」なしで実行できます

case
  when fieldid = 2 then data
  when fieldid = 35 then data
  else null
end

また、どちらの場合も同じ「データ」フィールドを返しているようです

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top