mysql находит недостающие элементы

#mysql #sql

#mysql #sql

Вопрос:

у меня есть таблица со следующей структурой

 mysql> describe stock_prices;
 --------------------- ------------- ------ ----- --------- ---------------- 
| Field               | Type        | Null | Key | Default | Extra          |
 --------------------- ------------- ------ ----- --------- ---------------- 
| id                  | int(11)     | NO   | PRI | NULL    | auto_increment |
| code                | varchar(16) | YES  | MUL | NULL    |                |
| pricelist           | varchar(10) | YES  | MUL | NULL    |                |
| settlement_discount | tinyint(1)  | YES  |     | NULL    |                |
| overal_discount     | tinyint(1)  | YES  |     | NULL    |                |
| sale                | tinyint(1)  | YES  |     | NULL    |                |
| price_blob          | longtext    | YES  |     | NULL    |                |
 --------------------- ------------- ------ ----- --------- ---------------- 
7 rows in set (0.00 sec)
  

когда я запускаю этот запрос

 mysql> SELECT pricelist, count(pricelist) as dup from stock_prices group by pricelist having dup>1 order by dup;
 ----------- ------ 
| pricelist | dup  |
 ----------- ------ 
| GMBH      | 1843 |
| DISTCART  | 2241 |
| DISTSTD   | 2241 |
| CART      | 2242 |
| USSD      | 2242 |
| SPCA      | 2242 |
| SPCB      | 2242 |
| SPCC      | 2242 |
| EUCN      | 2242 |
| STD       | 2242 |
| EUSD      | 2242 |
| USCN      | 2242 |
 ----------- ------ 
12 rows in set (0.03 sec)
  

все элементы прайс-листа должны иметь одинаковые значения, но у GMBH на 399 меньше, а у DISTCART и DISTSTD на 1 меньше.

в принципе, у меня есть code , у которого нет записи в прайс-листе.

когда я запускаю:

 mysql> SELECT code, count(code) as dup from stock_prices group by code having dup>1 order by dup;
 ------------- ----- 
| code        | dup |
 ------------- ----- 
| XN44-CH2    |   9 |
| XN23-MGY1   |  11 |
| XN24-CH2    |  11 |
| XN25-VWH1   |  11 |
| XN36-BL2    |  11 |
| XN36-CH3    |  11 |
| XN37-BL3    |  11 |
| XN38-BC3    |  11 |
| XN38-CE3    |  11 |
....
  

таким образом, в этом случае XN44-CH2 отсутствуют 3 кода и XN23-MGY1 отсутствует 1 код

 mysql> SELECT COUNT(pricelist) FROM stock_prices WHERE pricelist = 'GMBH';
 ------------------ 
| COUNT(pricelist) |
 ------------------ 
|             1843 |
 ------------------ 
1 row in set (0.00 sec)
  

каков был бы правильный способ узнать, каковы недостающие прейскуранты для каждого из них?

любой совет очень ценится.

Комментарии:

1. Пожалуйста, добавьте несколько примеров данных исходной таблицы.

2. Каков результат, если вы это сделаете? SELECT COUNT(pricelist) FROM stock_prices WHERE pricelist = 'GMBH'

3. я обновил вопрос

Ответ №1:

Предполагая, что существует справочная таблица для всех прайс-листов и одна для всех кодов, вы могли бы сделать что-то подобное в стандартном SQL:

 SELECT
  p.pricelist,
  c.code
FROM
  pricelists AS p
CROSS JOIN
  codes AS c

EXCEPT

SELECT
  pricelist,
  code
FROM
  stock_prices
;
  

То есть получить все комбинации существующих прайс-листов и кодов и вычесть те, которые присутствуют в stock_prices . Результатом будут недостающие пары.

Поскольку MySQL не поддерживает EXCEPT , вы могли бы реализовать ту же логику с LEFT JOIN :

 SELECT
  p.pricelist,
  c.code
FROM
  pricelists AS p
CROSS JOIN
  codes AS c
LEFT JOIN
  stock_prices AS s ON p.pricelist = s.pricelist
                   AND c.code = s.code
WHERE s.id IS NULL
;
  

Если у вас нет этих справочных таблиц, вы можете заменить их производными таблицами таким образом:

 pricelists  ==>  (SELECT DISTINCT pricelist FROM stock_prices)

codes  ==>  (SELECT DISTINCT code FROM stock_prices)
  

И тогда запрос будет выглядеть следующим образом:

 SELECT
  p.pricelist,
  c.code
FROM
  (SELECT DISTINCT pricelist FROM stock_prices) AS p
CROSS JOIN
  (SELECT DISTINCT code FROM stock_prices) AS c
LEFT JOIN
  stock_prices AS s ON p.pricelist = s.pricelist
                   AND c.code = s.code
WHERE s.id IS NULL
;