Я btc
таблицу, в которой показаны экземпляры, где более 1 записи содержат один и тот же btc
, но для разных btc
customer_names
, также показывающий мне самый низкий экземпляр cost
для каждого клиента.
Этот запрос работает, но он очень неэффективен, и для работы на столе в 80 000 строк требуется минута, поэтому я чувствую, что должен делать что-то неправильно.
select btc,customer_name,min(cost) from table where table.btc in
(select btc from table group by 1 having count(distinct customer_name) > 1)
group by 1,2
Это выводит таблицу следующим образом:
+---------+---------------+---------+
| btc | customer_name | cost |
+---------+---------------+---------+
| asd32 | Sony | 1.45863 |
| asd32 | Nintendo | 1.84839 |
| bf33940 | Sony | 2.49188 |
| bf33940 | Nintendo | 2.49188 |
| a43c3f | Sony | 2.84142 |
| a43c3f | Nintendo | 2.45 |
| a43c3f | Sega | 2.689 |
+---------+---------------+---------+
Я хотел бы сделать этот шаг дальше и НЕ включать какой-либо результат, где cost
обоих полей customer_name
одинакова (так что удаление btc bf33940
из приведенной выше таблицы, поскольку Sony и Nintendo имеют одинаковую стоимость)
Я также хотел бы знать, есть ли более эффективный способ делать то, что я делаю.
+------------------+--------------+------+-----+---------+
| field | type | null | key | default |
+------------------+--------------+------+-----+---------+
| btc | varchar(100) | NO | MUL | NULL |
| mpn | varchar(100) | YES | | NULL |
| supplier | varchar(100) | YES | | NULL |
| invoice | varchar(100) | YES | | NULL |
| invoice_date | datetime | YES | | NULL |
| qtr | varchar(5) | YES | | NULL |
| qty | double(10,0) | YES | | NULL |
| resale | double(15,5) | YES | | NULL |
| ext_resale | double(15,5) | YES | | NULL |
| cost | double(15,5) | YES | | NULL |
| ext_cost | double(15,5) | YES | | NULL |
| gpp | double(15,5) | YES | | NULL |
| project | varchar(100) | YES | | NULL |
| team | double(15,5) | YES | | NULL |
| build_type | varchar(50) | YES | | NULL |
| customer_name | varchar(100) | YES | | NULL |
| customer_address | varchar(100) | YES | | NULL |
| customer_type | varchar(100) | YES | | NULL |
| customer_group | varchar(100) | YES | | NULL |
| sps | varchar(100) | YES | | NULL |
| fps | varchar(100) | YES | | NULL |
| gps | varchar(100) | YES | | NULL |
| hps | varchar(100) | YES | | NULL |
+------------------+--------------+------+-----+---------+
образец файла CSV здесь: https://ufile.io/os0as
Вы могли бы попытаться заменить ваш, where...in
результате join
хотя трудно сказать, насколько эффективнее это будет без тестирования.
Что-то вроде этого:
select t1.btc, customer_name, min(cost)
from xxx t1
join (
select btc
from xxx
group by btc
having count(*) > 1
) t2 on t1.btc = t2.btc
group by t1.btc, t1.customer_name
Для вашего второго вопроса вы можете дополнительно группировать по btc и стоимости для удаления дубликатов:
select t3.btc, group_concat(t3.customer_name), min_cost
from (
select t1.btc, t1.customer_name, min(cost) as min_cost
from xxx t1
join (
select btc
from xxx
group by btc
having count(distinct customer_name) > 1
) t2 on t1.btc = t2.btc
) t3
group by t1.btc, t1.cost
Снова трудно сказать, будет ли это работать без тестирования, но, надеюсь, вы получите эту идею.
Чтобы ускорить работу, я сделал бы отдельную таблицу с каждым btc и счетчиком количества клиентов, поэтому вам не нужно создавать временную таблицу с count()> 1.
) t2 on t2 on t1.btc = t2.btc