我当前正在执行一个查询,该查询在选择中包含两个选择。我想对返回的结果进行分组以进行计数(进而创建饼图)
我要查询的系统包含一张图像表。每个图像可能具有零个或多个位元数据。可用的元数据因图像而异,因此它由单独的表而不是作为图像表的一部分的列提供服务。
所以表结构是:
Image {
image_id (PK)
}
ImageMetaDataKey {
metadata_key_id (PK),
key
}
ImageMetaDataValue {
metadata_value_id (PK),
value
}
ImageMetaData {
image_id (FK - Image.image_id),
metadata_key_id (FK - ImageMetaDataKey.metadata_key_id ),
metadata_value_id (FK - ImageMetaDataValue.metadata_value_id )
}
我当前的SQL语句是:
SELECT i_o.image_id, (SELECT imdv.value
FROM Image i, ImageMetaDataValue imdv, ImageMetaDataKey imdk, ImageMetaData imd
WHERE imdk.metadata_key_id = imd.metadata_key_id
AND imd.metadata_value_id =imdv.metadata_value_id
AND (imdk.key='Camera Model')
AND i.image_id=imd.image_id
) as Camera, (SELECT imdv.value
FROM Image i, ImageMetaDataValue imdv, ImageMetaDataKey imdk, ImageMetaData imd
WHERE imdk.metadata_key_id = imd.metadata_key_id
AND imd.metadata_value_id =imdv.metadata_value_id
AND (imdk.key='Lens Model')
AND i.image_id=imd.image_id
) as Lens
FROM Image i_o
GROUP BY i_o.image_id;
返回:
+----------+-----------------------+-------------------------------------+
| image_id | Camera | Lens |
+----------+-----------------------+-------------------------------------+
| 11 | Canon EOS 450D | EF-S17-55mm f/2.8 IS USM |
| 15 | Canon EOS 450D | EF-S17-55mm f/2.8 IS USM |
| 24 | Canon EOS 450D | EF-S17-55mm f/2.8 IS USM |
| 28 | Canon EOS 450D | EF16-35mm f/2.8L USM |
| 29 | Canon EOS 450D | EF16-35mm f/2.8L USM |
| 34 | Canon EOS 450D | EF-S18-55mm f/3.5-5.6 IS |
| 35 | Canon EOS 450D | EF-S18-55mm f/3.5-5.6 IS |
| 37 | Canon EOS 450D | EF-S17-55mm f/2.8 IS USM |
| 43 | Canon EOS 7D | EF-S17-55mm f/2.8 IS USM |
| 48 | Canon EOS 450D | EF-S17-55mm f/2.8 IS USM |
| 49 | Canon EOS 450D | EF70-200mm f/2.8L USM |
| 50 | Canon EOS 450D | EF70-200mm f/2.8L USM |
+----------+-----------------------+-------------------------------------+
理想情况下,我想运行以下内容:
SELECT COUNT(i_o.image_id) as 'Count ', (SELECT imdv.value
FROM Image i, ImageMetaDataValue imdv, ImageMetaDataKey imdk, ImageMetaData imd
WHERE imdk.metadata_key_id = imd.metadata_key_id
AND imd.metadata_value_id =imdv.metadata_value_id
AND (imdk.key='Camera Model')
AND i.image_id=imd.image_id
) as Camera, (SELECT imdv.value
FROM Image i, ImageMetaDataValue imdv, ImageMetaDataKey imdk, ImageMetaData imd
WHERE imdk.metadata_key_id = imd.metadata_key_id
AND imd.metadata_value_id =imdv.metadata_value_id
AND (imdk.key='Lens Model')
AND i.image_id=imd.image_id
) as Lens
FROM Image i_o
GROUP BY i_o.image_id, Camera, Lens;
将返回:
+----------+-----------------------+-------------------------------------+
| Count | Camera | Lens |
+----------+-----------------------+-------------------------------------+
| 5 | Canon EOS 450D | EF-S17-55mm f/2.8 IS USM |
| 2 | Canon EOS 450D | EF16-35mm f/2.8L USM |
| 2 | Canon EOS 450D | EF-S18-55mm f/3.5-5.6 IS |
| 1 | Canon EOS 7D | EF-S17-55mm f/2.8 IS USM |
| 2 | Canon EOS 450D | EF70-200mm f/2.8L USM |
+----------+-----------------------+-------------------------------------+
答案 0 :(得分:2)
我将使用两个聚合级别。首先获得两种模型:
SELECT imd.image_id,
MAX(CASE WHEN imdk.key = 'Camera Model' THEN imdv.value END) as camera_model,
MAX(CASE WHEN imdk.key = 'LENS Model' THEN imdv.value END) as lens_model
FROM ImageMetaData imd JOIN
ImageMetaDataKey imdk
ON imdk.metadata_key_id = imd.metadata_key_id JOIN
ImageMetaDataValue imdv
ON imd.metadata_value_id = imdv.metadata_value_id
GROUP BY imd.image_id;
然后将其用作子查询来获取计数:
SELECT camera_model, lens_model, COUNT(*)
FROM (SELECT imd.image_id,
MAX(CASE WHEN imdk.key = 'Camera Model' THEN imdv.value END) as camera_model,
MAX(CASE WHEN imdk.key = 'LENS Model' THEN imdv.value END) as lens_model
FROM ImageMetaData imd JOIN
ImageMetaDataKey imdk
ON imdk.metadata_key_id = imd.metadata_key_id JOIN
ImageMetaDataValue imdv
ON imd.metadata_value_id = imdv.metadata_value_id
GROUP BY imd.image_id
) cl
GROUP BY camera_model, lens_model;
非常重要地注意使用正确,显式,标准 JOIN
语法。
答案 1 :(得分:1)
因为我发现这个问题很有趣,所以我对第一个查询的结果进行了反向工程,从而创建了SQLFiddle。然后,我像这样重写查询:
SELECT i.image_id,
imdata1.value AS Camera,
imdata2.value AS Lens
FROM Image i
JOIN (SELECT imd1.image_id, imdv1.value FROM ImageMetaData imd1
JOIN ImageMetaDataKey imdk1
ON imdk1.metadata_key_id = imd1.metadata_key_id AND
imdk1.key = 'Camera Model'
JOIN ImageMetaDataValue imdv1
ON imdv1.metadata_value_id = imd1.metadata_value_id
) AS imdata1 ON imdata1.image_id = i.image_id
JOIN (SELECT imd2.image_id, imdv2.value FROM ImageMetaData imd2
JOIN ImageMetaDataKey imdk2
ON imdk2.metadata_key_id = imd2.metadata_key_id AND
imdk2.key = 'Lens Model'
JOIN ImageMetaDataValue imdv2
ON imdv2.metadata_value_id = imd2.metadata_value_id
) AS imdata2 ON imdata2.image_id = i.image_id
输出:
image_id Camera Lens
11 Canon EOS 450D EF-S17-55mm f/2.8 IS USM
15 Canon EOS 450D EF-S17-55mm f/2.8 IS USM
24 Canon EOS 450D EF-S17-55mm f/2.8 IS USM
28 Canon EOS 450D EF16-35mm f/2.8L USM
29 Canon EOS 450D EF16-35mm f/2.8L USM
34 Canon EOS 450D EF-S18-55mm f/3.5-5.6 IS
35 Canon EOS 450D EF-S18-55mm f/3.5-5.6 IS
37 Canon EOS 450D EF-S17-55mm f/2.8 IS USM
43 Canon EOS 7D EF-S17-55mm f/2.8 IS USM
48 Canon EOS 450D EF-S17-55mm f/2.8 IS USM
49 Canon EOS 450D EF70-200mm f/2.8L USM
50 Canon EOS 450D EF70-200mm f/2.8L USM
我改写它的原因是将其放入更适合分组的形式:
SELECT COUNT(i.image_id) AS `Count`,
imdata1.value AS Camera,
imdata2.value AS Lens
FROM Image i
JOIN (SELECT imd1.image_id, imdv1.value FROM ImageMetaData imd1
JOIN ImageMetaDataKey imdk1
ON imdk1.metadata_key_id = imd1.metadata_key_id AND
imdk1.key = 'Camera Model'
JOIN ImageMetaDataValue imdv1
ON imdv1.metadata_value_id = imd1.metadata_value_id
) AS imdata1 ON imdata1.image_id = i.image_id
JOIN (SELECT imd2.image_id, imdv2.value FROM ImageMetaData imd2
JOIN ImageMetaDataKey imdk2
ON imdk2.metadata_key_id = imd2.metadata_key_id AND
imdk2.key = 'Lens Model'
JOIN ImageMetaDataValue imdv2
ON imdv2.metadata_value_id = imd2.metadata_value_id
) AS imdata2 ON imdata2.image_id = i.image_id
GROUP BY Camera, Lens
输出:
Count Camera Lens
5 Canon EOS 450D EF-S17-55mm f/2.8 IS USM
2 Canon EOS 450D EF-S18-55mm f/3.5-5.6 IS
2 Canon EOS 450D EF16-35mm f/2.8L USM
2 Canon EOS 450D EF70-200mm f/2.8L USM
1 Canon EOS 7D EF-S17-55mm f/2.8 IS USM