Mysql 用于获取与多个表中的其他映射项相关的列计数的sql查询

Mysql 用于获取与多个表中的其他映射项相关的列计数的sql查询,mysql,sql,database,Mysql,Sql,Database,我在mysql表中有下表 广告显示器 ╔═══════╦══════════╗ ║ ADVID ║ ADTYPEID ║ ╠═══════╬══════════╣ ║ 1 ║ 1 ║ ║ 2 ║ 1 ║ ║ 3 ║ 4 ║ ║ 3 ║ 3 ║ ║ 2 ║ 2 ║ ║ 1 ║ 4 ║ ║ 1 ║ 3 ║ ║ 4 ║ 1 ║

我在mysql表中有下表

广告显示器

╔═══════╦══════════╗
║ ADVID ║ ADTYPEID ║
╠═══════╬══════════╣
║     1 ║        1 ║
║     2 ║        1 ║
║     3 ║        4 ║
║     3 ║        3 ║
║     2 ║        2 ║
║     1 ║        4 ║
║     1 ║        3 ║
║     4 ║        1 ║
║     4 ║        1 ║
╚═══════╩══════════╝
媒体类型

╔═════════╦═══════════╗
║ MEDIAID ║ MEDIANAME ║
╠═════════╬═══════════╣
║       1 ║ Animation ║
║       2 ║ video     ║
║       3 ║ Image     ║
╚═════════╩═══════════╝
a_ad_类型

╔══════════╦════════╗
║ ADTYPEID ║ ADTYPE ║
╠══════════╬════════╣
║        1 ║ e Ad   ║
║        2 ║ b Ad   ║
║        3 ║ c Ad   ║
║        4 ║ d Ad   ║
╚══════════╩════════╝
广告

╔═══════╦═════════╗
║ ADVID ║ MEDIAID ║
╠═══════╬═════════╣
║     1 ║       1 ║
║     2 ║       1 ║
║     3 ║       2 ║
║     4 ║       3 ║
╚═══════╩═════════╝
现在我想拿的东西如下

adType  | Image | video  | Animation
eAd     |    0  |    2   |    2 ...
b Ad    |...
c Ad    |...
d Ad    |.....
像wise一样,我需要所有的adtype数据。有人能为我提供这方面的指导吗

这就是我尝试过的

SELECT Distinct
at.adtype,
COUNT(IF(am.medianame = 'Animation',1,0)) AS Animation,
COUNT(IF(am.medianame = 'Video',1,0)) AS Video,
COUNT(IF(am.medianame = 'Image',1,0)) AS Image
FROM a_ad_type as at
LEFT JOIN a_ad_display as ad ON at.adtypeId = ad.adtypeId
LEFT JOIN a_advertise as adv ON adv.advertiseId = ad.advId
LEFT JOIN a_mediatype as am ON am.mediaId = adv.mediaTypeId
GROUP BY at.adtype

您需要使用公共列连接表,如

SELECT ad.adtype
      ,am.medianame
FROM   a_ad_type ad
       INNER JOIN
       a_ad_display add ON ad.adTypeId=add.adTypeId
       INNER JOIN
       a_advertise a ON add.advId=a.advId
       INNER JOIN
       a_mediatype am ON am.mediaId=a.mediaId
然后,您需要透视此查询的结果。数据透视是特定于数据库的语法,我不熟悉如何在mysql中进行数据透视(我总是需要在SQL Server中查找数据透视!),但如果您搜索数据透视,我相信您会找到它

SELECT  a.adtype,
        SUM(CASE WHEN d.medianame = 'Image' THEN  1 ELSE 0 END) `Image`,
        SUM(CASE WHEN d.medianame = 'video' THEN  1 ELSE 0 END) `video`,
        SUM(CASE WHEN d.medianame = 'Animation' THEN  1 ELSE 0 END) `Animation`
FROM    a_ad_type a
        LEFT JOIN a_ad_display b
            ON a.adtypeId = b.adtypeId
        LEFT JOIN  a_advertise c
            ON b.advId = c.advId
        LEFT JOIN a_mediatype d
            ON c.mediaId = d.mediaId
GROUP   BY a.adtype
更新1

如果您有多个
medianame
值,但您没有;我不希望它一个接一个地指定。您可以为此创建*动态SQL8

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'SUM(CASE WHEN d.medianame = ''',
      medianame,
      ''' then 1 ELSE 0 end) AS `',medianame,'`'
    )
  ) INTO @sql
FROM a_mediatype;

SET @sql = CONCAT('SELECT   a.adtype, ', @sql, ' 
                  FROM  a_ad_type a
                          LEFT JOIN a_ad_display b
                              ON a.adtypeId = b.adtypeId
                          LEFT JOIN  a_advertise c
                              ON b.advId = c.advId
                          LEFT JOIN a_mediatype d
                              ON c.mediaId = d.mediaId
                  GROUP   BY a.adtype');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

这就是我解决问题的方法。如果有人发现错误,请纠正我。谢谢你。

表格之间的关系如何?这不是提问的方法。你知道sql连接吗?你的背景是什么?你试过什么?请看我的最新问题…和我的老问题…哪一个没有给我正确的结果现在可以吗@jurgenrezza@BhavikKama是的,好多了。始终包括你尝试过的和你得到的结果,以及为什么它不是你想要的。现在我们知道你应该用SUM来代替COUNT和CASE,而不是IF,这样你就可以了。thanx mite…但是我想用水平的方式来计算medianame…就像我在上表的问题中所说的那样…请看我的答案…我已经解决了这个问题…请检查一下…如果我错了,请纠正我你可以省略关键字了
DISTINCT
因为您已经在.adtype上按
对它进行分组了。您能看到我回答的查询吗?是更好还是更好?没有问题,但它是静态的。如果在表
medianame
上有多个值,则它将不灵活。
 SELECT Distinct
at.adtype,

COUNT(CASE am.mediaId WHEN 1 THEN at.adtypeId END) As Animation,
COUNT(CASE am.mediaId WHEN 2 THEN at.adtypeId END) As Video,
COUNT(CASE am.mediaId WHEN 3 THEN at.adtypeId END) As Image
FROM a_ad_type as at
LEFT JOIN a_ad_display as ad ON at.adtypeId = ad.adtypeId
LEFT JOIN a_advertise as adv ON adv.advertiseId = ad.advId
LEFT JOIN a_mediatype as am ON am.mediaId = adv.mediaTypeId
GROUP BY at.adtype