MySQL CASE“それ以外の場合”前提条件が真のときに実行されている-私は何が欠けていますか?
質問
私が使用しているサードパーティのシステムにより、データが重複しているテーブルがあります。モデルは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
また、どちらの場合も同じ「データ」フィールドを返しているようです