#mysql
#mysql
Вопрос:
У меня есть запрос к таблице телефонных звонков, который использует GROUP BY для отображения только уникальных идентификаторов вызывающих абонентов. Проблема в том, что если у вызывающего абонента заблокирован идентификатор вызывающего абонента, его идентификатор вызывающего абонента отображается как «Неизвестный», и клиент не хочет, чтобы все неизвестные суммировались вместе. Итак, в принципе, вместо того, чтобы просто GROUP BY caller_id
мне нужно как-то сделать что-то вроде GROUP BY caller_id IF caller_id != 'Unknown'
Возможно ли это вообще? Я бы хотел избежать выполнения всей групповой обработки в PHP, если это вообще возможно.
Комментарии:
1. Разве для этого не используется оператор WHERE?
2. Ответ VladoDemcak кажется нормальным … это работает для вас?
Ответ №1:
Вы можете сделать что-то вроде:
SELECT caller_id FROM phone_calls WHERE caller_id != 'Unknown' GROUP BY caller_id;
или рассмотрите DISTINCT — в большинстве случаев это быстрее — если у вас есть индекс, созданный для caller_id, производительность обычно такая же, но если не DISTINCT, то лучше. Если вам нужно :
… показывать только уникальные идентификаторы вызывающих абонентов..
но, возможно, для вашего случая (выполнение агрегации или что-то подобное) вы не можете его использовать, но на всякий случай:
SELECT DISTINCT caller_id FROM phone_calls WHERE caller_id != 'Unknown'
;
— РЕДАКТИРОВАТЬ ПОСЛЕ обсуждения в комментариях
SELECT * FROM callers;
---- ----------- -----------
| id | caller_id | call_time |
---- ----------- -----------
| 1 | abc | 24 |
| 2 | abc | 16 |
| 3 | xyz | 10 |
| 4 | xyz | 10 |
| 5 | Unknown | 11 |
| 6 | Unknown | 12 |
| 7 | Unknown | 13 |
| 8 | xyz | 1 |
| 9 | abc | 10 |
---- ----------- -----------
SELECT caller_id, SUM(call_time) FROM callers
WHERE caller_id != 'Unknown'
GROUP BY caller_id;
----------- ----------------
| caller_id | SUM(call_time) |
----------- ----------------
| abc | 50 |
| xyz | 21 |
----------- ----------------
SELECT caller_id, SUM(call_time) FROM callers
GROUP BY caller_id;
----------- ----------------
| caller_id | SUM(call_time) |
----------- ----------------
| abc | 50 |
| Unknown | 36 |
| xyz | 21 |
----------- ----------------
SELECT caller_id, SUM(call_time) as total_time FROM callers
WHERE caller_id != 'Unknown'
GROUP BY caller_id
UNION
SELECT caller_id, call_time FROM callers
WHERE caller_id = 'Unknown';
----------- ------------
| caller_id | total_time |
----------- ------------
| abc | 50 |
| xyz | 21 |
| Unknown | 11 |
| Unknown | 12 |
| Unknown | 13 |
----------- ------------
SELECT caller_id, SUM(call_time) as total_time FROM callers
GROUP BY caller_id,
(case when caller_id = 'Unknown'
AND id is not null
then id end
);
----------- ------------
| caller_id | total_time |
----------- ------------
| abc | 50 |
| Unknown | 11 |
| Unknown | 12 |
| Unknown | 13 |
| xyz | 21 |
----------- ------------
Комментарии:
1. Мы выполняем агрегацию, поэтому DISTINCT не работает. И мы по-прежнему хотим, чтобы неизвестные вызовы отображались, просто каждый как своя группа (поэтому каждый вызов с идентификатором вызывающего абонента Unknown будет отображаться в результатах со счетом 1), и я думаю, что предложение WHERE полностью удалит их. Это сработало бы, если бы я просто сделал второй запрос, чтобы выбирать только вызовы с caller_id из Unknown и не выполнять никакой группировки по этому второму запросу
2. Хорошо, теперь я понимаю, что вам действительно нужно. Есть одна возможность, но сейчас я не могу ее проверить, но вы можете попробовать «группировать по caller_id, (случай, когда caller_id = ‘Unknown’ и unique_col не равен нулю, тогда unique_col заканчивается);» но для неизвестной группы должен быть уникальный столбец. В противном случае, я думаю, вам понадобятся два выбора и объединение их.
3. @awestover89 проверьте мой ответ, я добавил примеры, это было бы вам интересно
4. В итоге я создал переменную. Рассматриваемый запрос уже составлял около 60 строк, поэтому ОБЪЕДИНЕНИЕ было бы ужасно неэффективным. Мое окончательное решение оказалось чем-то вроде: IF (0 = ani REGEXP ‘^[ ]?[0-9] $’,@ani_count:=@ani_count 1,@ani_count:=0) КАК unknown_count, а затем добавил unknown_count в группу. Я думаю, что функционально это ведет себя так же, как и ваш последний пример.
5. По сути, я создал переменную, которая была бы одинаковой для всех числовых идентификаторов вызывающих абонентов и уникальным значением для любого нечислового caller_id, поэтому, когда я группируюсь по ani и unknown_count, нечисловые идентификаторы вызывающих абонентов находятся в отдельной группе.