Очень конкретный запрос - это можно решить? - PullRequest
0 голосов
/ 15 ноября 2011

У меня есть две таблицы:

марка

  • основной штамп_ид,
  • firstStampIdInSerie_id (то же самое для марок из одной серии)
  • производный_стамп_ид (пометить штамп_идей (из таблицы), принадлежащему штампу-идентику той же строки)

stampsincatalogs

  • catalogueNember_prepend, catalogue_number и catalogueNumber_append (эти столбцы определяют номер каталога)

Этот запрос довольно прост, но все еще работает. Возвращает диапазон серийных и числовых штампов, но из диапазона производных возвращаемых серий только первый catalogueNumber и numberDerivatedStamps не верны (показывать одинаковое число извести numberStamps). Я думаю, что это проблема с GROUP BY. Можно ли собрать запрос, который будет делать то, что должен делать?

SELECT CONCAT_WS('-', CONCAT_WS('/', s.catalogueNumber_prepend,
       MIN(s.catalogue_number), s.catalogueNumber_append), 
       IF (MAX(s.catalogue_number) != MIN(s.catalogue_number), 
       CONCAT_WS('/', s.catalogueNumber_prepend, MAX(s.catalogue_number),
       s.catalogueNumber_append), NULL)) AS `rangeOfCatNumbers`, 
       COUNT(s.catalogue_number) AS `numberStamps`, CONCAT_WS('-', 
       CONCAT_WS('/', ds.catalogueNumber_prepend, MIN(ds.catalogue_number),
       ds.catalogueNumber_append), 
       IF (MAX(ds.catalogue_number) != MIN(ds.catalogue_number), 
       CONCAT_WS('/', ds.catalogueNumber_prepend, 
       MAX(ds.catalogue_number), ds.catalogueNumber_append), NULL)) AS `rangeOfDerivatedCatNumbers`, 
       COUNT(ds.catalogue_number) AS `numberDerivatedStamps` FROM `stamps`
LEFT JOIN `stampsincatalogs` AS `s` ON stamps.stamp_id = s.stamp_id
LEFT JOIN `stampsincatalogs` AS `ds` ON stamps.derivatedStamp_id = ds.stamp_id
GROUP BY `firstStampIdInSerie_id`

СТОЛОВЫЕ марки

stamp_id | firstStampsIdInSerie_id | derivatedStamp_id
1        | 1                       | 6
2        | 1                       | NULL
3        | 3                       | NULL
4        | 3                       | NULL
5        | 3                       | NULL
6        | 6                       | 1

ТАБЛИЦА штампов-каталогов

id | stamp_id | catalogueNumber_prepend | catalogue_number | catalogueNumber_append
1  | 1        | NULL                    | 100              | A
2  | 2        | NULL                    | 101              | A
3  | 3        | NULL                    | 102              | A
4  | 4        | NULL                    | 103              | C
5  | 5        | NULL                    | 104              | C
6  | 6        | B                       | 8                | NULL

Ожидаемый результат:

100/A - 102/A | 3 | B/8           | 1
103/C - 104/C | 2 | NULL          | 0
6/B           | 1 | 100/A - 102/A | 3

Заданный результат:

100/A - 102/A | 3 | B/8   | 1
103/C - 104/C | 2 | NULL  | 0
6/B           | 1 | 100/A | 1

Спасибо всем за советы

Томас

Редактировать: Извините, я вставил свой первый вопрос, теперь он отформатирован:).


Я решил, но его нельзя использовать, потому что запрос durate 53 секунды :(. Как я могу оптимизировать?

SELECT CONCAT_WS('-', 
                 CONCAT_WS('/',
                           s.catalogueNumber_prepend,
                           MIN(s.catalogue_number),
                           s.catalogueNumber_append), 
                 IF (MAX(s.catalogue_number) != MIN(s.catalogue_number), 
                     CONCAT_WS('/',
                               s.catalogueNumber_prepend,
                               MAX(s.catalogue_number),
                               s.catalogueNumber_append), 
                     NULL))                AS `rangeOfCatNumbers`, 
       COUNT(s.catalogue_number)  AS `numberStamps`, 
       CONCAT_WS('-', 
                 CONCAT_WS('/',
                           ds.catalogueNumber_prepend,
                           MIN(ds.catalogue_number),
                           ds.catalogueNumber_append), 
                 IF (MAX(ds.catalogue_number) != MIN(ds.catalogue_number), 
                     CONCAT_WS('/',
                               ds.catalogueNumber_prepend,
                               MAX(ds.catalogue_number),
                               ds.catalogueNumber_append), 
                     NULL))                AS `rangeOfDerivatedCatNumbers`, 
       COUNT(DISTINCT ds.catalogue_number) AS `numberDerivatedStamps` 
FROM `stamps`
LEFT JOIN `stampsincatalogs` AS `s` ON stamps.stamp_id = s.stamp_id
LEFT JOIN `stamps` AS `tmp` ON tmp.firstStampIdInSerie_id = stamps.derivatedStamp_id
LEFT JOIN `stampsincatalogs` AS `ds` ON tmp.stamp_id = ds.stamp_id
GROUP BY `firstStampIdInSerie_id`

Ответы [ 2 ]

1 голос
/ 15 ноября 2011

Похоже, вам просто нужно изменить COUNT(...) на COUNT(DISTINCT ...) - вот так:

SELECT CONCAT_WS('-', 
                 CONCAT_WS('/',
                           s.catalogueNumber_prepend,
                           MIN(s.catalogue_number),
                           s.catalogueNumber_append), 
                 IF (MAX(s.catalogue_number) != MIN(s.catalogue_number), 
                     CONCAT_WS('/',
                               s.catalogueNumber_prepend,
                               MAX(s.catalogue_number),
                               s.catalogueNumber_append), 
                     NULL))                AS `rangeOfCatNumbers`, 
       COUNT(DISTINCT s.catalogue_number)  AS `numberStamps`, 
       CONCAT_WS('-', 
                 CONCAT_WS('/',
                           ds.catalogueNumber_prepend,
                           MIN(ds.catalogue_number),
                           ds.catalogueNumber_append), 
                 IF (MAX(ds.catalogue_number) != MIN(ds.catalogue_number), 
                     CONCAT_WS('/',
                               ds.catalogueNumber_prepend,
                               MAX(ds.catalogue_number),
                               ds.catalogueNumber_append), 
                     NULL))                AS `rangeOfDerivatedCatNumbers`, 
       COUNT(DISTINCT ds.catalogue_number) AS `numberDerivatedStamps` 
FROM `stamps`
LEFT JOIN `stampsincatalogs` AS `s` ON stamps.stamp_id = s.stamp_id
LEFT JOIN `stampsincatalogs` AS `ds` ON stamps.derivatedStamp_id = ds.stamp_id
GROUP BY `firstStampIdInSerie_id`

COUNT (x) возвращает общее число ненулевых значений x, найденных вгруппа, тогда как COUNT (DISTINCT x) возвращает количество найденных значений x.

0 голосов
/ 17 ноября 2011

Решено уменьшением длительности запроса на 0,03 сек

LEFT JOIN `stamps` AS `tmp` ON tmp.firstStampIdInSerie_id = stamps.derivatedStamp_id AND tmp.country_id = stamps.country_id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...