我有多个表,我想加入这些表以获得特定结果。
表格是:
ad_categories, ad_image, ad_data, ad_location
我需要为 ad_categories 表中的以下每一行输出一行,无论在使用 WHERE 条件时是否存在特定位置的任何这些类别的数据。
mysql> SELECT type FROM ad_categories;
+---------------+
| type |
+---------------+
| restaurants |
| fitness |
| funactivities |
| shopping |
| homes |
| men |
+---------------+
例如:
mysql> SELECT alias, type, sha, originalname FROM ad_categories LEFT JOIN ad_data ON ad_data.cid=ad_categories.id LEFT JOIN ad_image ON ad_image.pid=ad_data.id LEFT JOIN ad_location ON ad_location.id=ad_data.lid GROUP BY type;
+--------+---------------+------------------------------------------+---------------------------------+
| alias | type | sha | originalname |
+--------+---------------+------------------------------------------+---------------------------------+
| malibu | fitness | ad8b277202f4ded274274744b3fa28f34e9f1c21 | thai_body_works.jpg |
| malibu | funactivities | 6a226df8ff827aa020b077e9e0d48e4701ae2fca | rosenthal-the_malibu_estate.jpg |
| NULL | homes | NULL | NULL |
| NULL | men | NULL | NULL |
| malibu | restaurants | 98f357dfa5bdb2eb1d480dc0e8b7156b1eecac31 | moonshadows.jpg |
| malibu | shopping | 1b2ef538691569842b9f9fb6c3816673f334205a | malibu_surf_shack.jpg |
+--------+---------------+------------------------------------------+---------------------------------+
6 rows in set (0.00 sec)
列出了我需要的所有类别类型,但我没有指定我需要做的位置。我只想要每种类型、每个指定位置的一行。如果该位置的类别类型不存在数据,请为类型以外的列填写空值。
mysql> SELECT alias, type, sha, originalname FROM ad_categories LEFT JOIN ad_data ON ad_data.cid=ad_categories.id JOIN ad_image ON ad_image.pid=ad_data.id LEFT JOIN ad_location ON ad_location.id=ad_data.lid WHERE ad_location.alias='malibu' GROUP BY type;
+--------+---------------+------------------------------------------+---------------------------------+
| alias | type | sha | originalname |
+--------+---------------+------------------------------------------+---------------------------------+
| malibu | fitness | ad8b277202f4ded274274744b3fa28f34e9f1c21 | thai_body_works.jpg |
| malibu | funactivities | 6a226df8ff827aa020b077e9e0d48e4701ae2fca | rosenthal-the_malibu_estate.jpg |
| malibu | restaurants | 98f357dfa5bdb2eb1d480dc0e8b7156b1eecac31 | moonshadows.jpg |
| malibu | shopping | 1b2ef538691569842b9f9fb6c3816673f334205a | malibu_surf_shack.jpg |
+--------+---------------+------------------------------------------+---------------------------------+
4 rows in set (0.00 sec)
我不是专业的 SQL 忍者。如果我错误地构建了 SQL 查询,有人可以纠正我,或者可以通过一些线索来指导我如何正确完成我想做的事情吗?谢谢。
最佳答案
使用:
SELECT alias, type, sha, originalname
FROM (SELECT alias,
type,
sha,
originalname,
CASE WHEN @type = type THEN @rownum := @rownum + 1 ELSE @rownum := 1 END AS rank,
@type := type
FROM AD_CATEGORIES c
LEFT JOIN AD_DATA d ON d.cid = c.id
LEFT JOIN AD_LOCATION l ON l.id = d.lid
AND l.alias = ?
LEFT JOIN AD_IMAGE i ON i.pid = d.id
JOIN (SELECT @rownum := 0, @type := '') r
ORDER BY type, l.id DESC) x
WHERE x.rank = 1
我唯一没有的是我假设 AD_LOCATION
中的哪一列,您将指定“malibu”/etc 作为位置。 ORDER BY 很重要,以确保非 NULL 别名/位置排在 NULL 之前...
分割
这个:
JOIN (SELECT @rownum := 0, @type := '') r
...允许您定义和初始化变量,而无需使用单独的 SET 命令。
这些:
CASE
WHEN @type = type THEN @rownum := @rownum + 1 -- increments rownum when type matches
ELSE @rownum := 1 -- resets rownum to 1 when @type != type
END AS rank,
@type := type -- need this to set @type for the next rows comparison
请查看“--”之后的内容以进行逐行注释。
ORDER BY type, l.id DESC
必须使用 ORDER BY 来保持类型值的顺序,否则排名值将不会如我们所愿。 ORDER BY 的第二部分确保非 NULL 的位置值首先出现,如果有任何基于过滤的话。
最后,外部查询只得到rank值为1的行...
关于sql - 连接查询是否正确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3535420/