2009-10-25 2 views
0

У меня есть таблица, которая из-за использования сторонней системы, которую мы используем, иногда имеет повторяющиеся данные. Поскольку модель использует метод EAV, нет никакого способа отфильтровать этот «правильный» способ, поэтому я собираю данные в представлении. Я знаю, что это проблема сбора данных, но мне легче исправить ее на дисплее, чем пройдите эту систему и потенциально повредите существующие данные и формы. Мне нужно проверить одно из двух полей, чтобы увидеть, введен ли один или оба, но выбрать только один (иначе имя отображается дважды: «Джон, Джон», а не просто «Джон»). Вот мой код для соответствующей части:MySQL CASE «Else Case When» выполняется, когда условие является истинным - что мне не хватает?

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 введены, я бы ожидать, что это просто возвращает значение из fieldid = 2, а не значение из fieldid = 35, так как ELSE не должно выполняться, когда исходный случай, когда это правда. Однако он захватывает это, а затем все еще выполняет случай, когда внутри предложения else?

Как я могу исправить этот код, чтобы дать мне либо fieldid = 2 OR fieldid = 35, но и избежать их одновременного слияния, что приводит к дублированию имени?

РЕДАКТИРОВАТЬ

Вот структура таблицы:

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

Он использует структуру EAV поэтому образец запись может быть:

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

с fieldid 2 и 35 является пользовательское поле «Имя» (определенное в отдельной таблице), а поле 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 (мы называем поле list.name в таблице списков с помощью числового идентификатора, который создается нашим внешним интерфейсом Rails при добавлении нового пользователя, поэтому я извлекаю только этот номер, чтобы сделать вид похожим таблица базы данных Rails-соглашений)

ответ

1

Все внутри group_concat() не есть способ, чтобы увидеть контекст, в котором он работает. Таким образом, у вас есть две строки в одной группе, один с fieldid=2 и второй с fieldid=35, он будет делать следующее:

  • обработки строк с fieldid=2 ...
    • s.fieldid = 2 правда, вернуться s.data
  • обрабатывающий ряд с fieldid=35 ...
    • s.fieldid = 2 ложна, попробуйте else часть
    • s.fieldid = 35 верно, возвращение s.data

Это объясняет, почему "Джон" возвращается несколько раз. Единственный способ исправить это - запустить другой запрос за пределами group_concat().

EDIT:

Ih вы действительно должны сделать это таким образом, использовать что-то вроде этого, вместо:

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

В качестве альтернативы вы можете сделать group_concat(DISTINCT ...), если два значения не могут быть разными (иначе вы получите, например, «Джон, Джонни»). Почему у вас есть два значения для first_name/last_name?

+0

Любая идея, как с этим справиться? Я могу удалить group_concat из образца, показанного выше, и, похоже, он работает, но делать это с другим (с разными идентификаторами) не дает мне результата, даже если они оба есть, но сохранение group_concat все равно дает его мне дважды. –

+0

Отправьте фактический запрос, который вы используете, и структуру таблицы. –

+0

Использование его без group_concat также, похоже, не дает мне данных для некоторых записей, где данные существуют. Это очень странно и запутанно. –

2

Я не парень mysql, но в случае с регистром сервера sql вы можете сделать это без первого 'else'

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

Кроме того, вы, кажется, возвращая то же поле «данные» в обоих случаях

+0

Поле «данные» - это вещь EAV, о которой я говорил. Fieldid ссылается на список настраиваемых полей (имя и т. Д., Но может быть и определено как mroe, чем один раз - и 2, и 35 - это «имя»), а данные являются фактическим значением (поэтому в этом случае оба содержат «John»,). Дело в том, что все еще дает мне оба поля - я хочу только одного или другого. –

+0

В основном у меня был код выше: сначала «Джон, Джон», но я хочу, чтобы это просто «Джон». –

+0

Вам нужно будет показать еще какой-то код, а затем WayneM. Что происходит вокруг этого 'group_concat()'? –

Смежные вопросы