非常具体的查询 - 它可以解决?

时间:2011-11-15 10:16:23

标签: mysql sql

我有两张桌子:

邮票

  • primary stamp_id,
  • firstStampIdInSerie_id(对于来自一个系列的邮票是相同的)
  • derivatedStamp_id(mark stamp_id(来自表)属于同一行的stamp_id)

stampsincatalogs

  • catalogueNember_prepend,catalogue_number和catalogueNumber_append(这些列确定目录号)

这个查询非常简单,但仍然有效。返回系列和数字标记的范围,但是从衍生系列返回的范围仅第一个catalogueNumber和numberDerivatedStamps不正确(显示相同的数字lime 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`

TABLE标记

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

TABLE stampsincatalogs

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

感谢大家的建议

托马斯

编辑:我很抱歉我插入了我的第一个问题,所以现在格式化了:)。


我解决了,但它无法使用,因为查询持续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 个答案:

答案 0 :(得分:1)

看起来您只需要将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的不同值的数量。

答案 1 :(得分:0)

通过在0,03秒减少持续时间查询来解决

LEFT JOIN `stamps` AS `tmp` ON tmp.firstStampIdInSerie_id = stamps.derivatedStamp_id AND tmp.country_id = stamps.country_id