【问题标题】:How to write JOIN QUERY for 4 tables in the below condition如何在以下条件下为 4 个表编写 JOIN QUERY
【发布时间】:2013-05-29 13:23:29
【问题描述】:

我有 4 张桌子 ACCOUNTS_TABLE , LINKS_TABLE, GROUPS_TABLE, KEYS_TABLE

我需要得到 all accounts details ,它是 acct_type xxcount of Links, groups& keywords 。我试过这个查询,但它给出了所有count as 0

SELECT 
    acc.acct_id, acc.acct_type, count(link.id) as link_count, link.account, 
    groups.camp_id, count(groups.id) as group_count, count(keyword.key_id) as key_count 

FROM ".ACCOUNTS_TABLE." as acc  
    LEFT JOIN ".LINKS_TABLE." as link ON link.account=acc.acct_id AND acct_type='xx' 
    LEFT JOIN  ".GROUPS_TABLE." as groups ON  groups.camp_id=link.id 
    LEFT JOIN ".KEYS_TABLE." as keyword ON keyword.camp_id=link.id 

GROUP BY acc.acct_id 

我需要的输出应该是这样的

任何人请帮我解决这个问题

【问题讨论】:

    标签: php mysql join count left-join


    【解决方案1】:

    您可能应该使用 COUNT(DISTINCT ....)。

    SELECT acc.acct_id, COUNT(DISTINCT link.id), COUNT(DISTINCT groups.id), COUNT(DISTINCT keyword.key_id)
    FROM ACCOUNTS_TABLE acc
    LEFT OUTER JOIN LINKS_TABLE link ON link.account = acc.acct_id AND acct_type = 'advertiser'
    LEFT OUTER JOIN GROUPS_TABLE groups ON  groups.camp_id = link.id 
    LEFT JOIN KEYS_TABLE keyword ON keyword.id = link.id 
    WHERE acc.acct_type = 'xx'
    GROUP BY acc.acct_id
    

    编辑

    修改为使用更新的连接条件等:-

    SELECT acc.acct_id, acc.acct_type, COUNT( DISTINCT link.id ) , COUNT( DISTINCT groups.id ) , COUNT( DISTINCT keyword.key_id ) 
    FROM ACCOUNTS_TABLE acc
    LEFT OUTER JOIN LINKS_TABLE link ON link.account = acc.acct_id
    LEFT OUTER JOIN GROUPS_TABLE groups ON groups.camp_id = link.id
    LEFT JOIN KEYS_TABLE keyword ON keyword.camp_id=link.id 
    WHERE acc.acct_type = 'xx'
    GROUP BY acc.acct_id, acc.acct_type
    

    【讨论】:

    • 仍然将所有计数归零
    • 当我省略 GROUP BY acc.acct_id 时,它会正确给出总数。但我需要单独获取所有帐户!
    • 似乎阻止它用您的测试数据带回有用数据的事情是,您在链接表的连接中指定了“广告商”的 acct_type。没有匹配的记录。删除它会得到一些记录。您还指定使用 key_id 和链接表 id 加入密钥表。你想加入这些或 camp_id 更有意义吗?
    • 实际记录中xx的意思是advertiser。我已经更新了有问题的查询。这不是问题
    • 对不起,实际上keyword.id与真实数据中的camp_id相同key_id不同。我给了keyword.id 而不是key_id(现在更新了查询)
    【解决方案2】:

    你可以试试这样的:

    SELECT  ACC.Id
           ,( SELECT COUNT (*) FROM Links L WHERE L.AccountId = ACC.Id ) AS CountOfLinks
           ,( SELECT COUNT (*) FROM Groups G WHERE G.AccountId = ACC.Id ) AS CountOfGroups
    FROM    ( SELECT Id FROM Accounts Acc WHERE Acc.Type = 'some type' ) ACC
    

    【讨论】:

    • Co 相关子查询非常昂贵。
    • @OlivierCoilland:你说得对,你完全可以不用。
    • Groups 表没有 accountID...WHERE G.AccountId = ACC.Id
    【解决方案3】:

    出于以下几个原因,我稍微修改了您的代码(见下文):

    1. 总是以某种方式编写我的 SELECT 语句是有帮助的(无论如何对我来说) - 将未分组的任何内容放在首位,理想情况下将事物按照与我的 JOIN 相同的顺序并在我的 GROUP BY 中执行相同的操作
    2. 我将任何限制我的 FROM 表的内容放入 WHERE 而不是 JOIN 中,以使我想要做的事情更清楚,也便于以后修改。
    3. 我还希望确保其布局合理,以便更轻松地扫描问题。

    接受这个重新排列的查询并通读它,以确保您获得了预期的行为。

    PS 我不确定您的表格名称和引用样式 - 我通常使用反引号 (`) 并且永远不会在表格名称中添加点 (.)。如果您将它们作为占位符放入,那很好,但如果它们是真实的,它们可能会给您带来麻烦。

    SELECT 
    acc.acct_id, 
    -- if you don't group by these then you need to remove them as they will just return the first values based on mysql behaviour
    acc.acct_type, 
    link.account,
    groups.camp_id,
    -- these counts will only count where an ID is present which seems like what you're after
    count(link.id) as link_count, 
    count(groups.id) as group_count, 
    count(keyword.key_id) as key_count
    FROM ".ACCOUNTS_TABLE." as acc  
    LEFT JOIN ".LINKS_TABLE." as link ON link.account=acc.acct_id 
    
    LEFT JOIN  ".GROUPS_TABLE." as groups ON  groups.camp_id=link.id 
    LEFT JOIN ".KEYS_TABLE." as keyword ON keyword.id=link.id 
    
    WHERE acct_type='advertiser' 
    
    GROUP BY acc.acct_id,  
    -- only use these if you intend to group by them  
    acc.acct_type, 
    link.account,
    groups.camp_id DESC
    

    【讨论】:

      【解决方案4】:
          SELECT acct_type,
             count(acct_type),
             count(l.id),
             count(g.id),
             count(key_id)
      FROM accounts a
      LEFT JOIN links l ON (l.account = a.acct_id)
      LEFT JOIN groups g ON (g.camp_id = l.id)
      LEFT JOIN keysTable k ON k.group_id = g.id
      GROUP BY acct_type HAVING acct_type = 'xx';
      

      SQL Fiddle 已验证:http://www.sqlfiddle.com/#!2/f4b6a/20

      【讨论】:

      • 我需要单独获取所有帐户详细信息。它只是给出总数。即,acc1 有 2 个链接 1 个组和 3 个关键字,acc2 有 3 个链接 3 个组和 1 个关键字。
      【解决方案5】:
      SELECT
        accounts_table.acct_id,
        accounts_table.acct_type,
        COUNT(DISTINCT links_table.id) AS link_count,
        COUNT(DISTINCT groups_table.id) AS group_count,
        COUNT(DISTINCT keys_table.key_id) AS key_count
      FROM 
        accounts_table
      LEFT JOIN 
        links_table
        ON links_table.account = accounts_table.acct_id
      LEFT JOIN 
        groups_table 
        ON groups_table.camp_id = links_table.id
      LEFT JOIN 
        keys_table 
        ON keys_table.camp_id = links_table.id
      WHERE 
        acct_type = 'xx'
      GROUP BY 
        accounts_table.acct_id,
        accounts_table.acct_type
      ORDER BY 
        link_count DESC,
        group_count DESC,
        key_count DESC
      

      编辑答案以匹配更新的问题 - 这应该符合您的要求。

      这应该可以满足您的要求,这里是 SQL 小提琴 - http://www.sqlfiddle.com/#!2/f4b6a/20

      【讨论】:

      • 这与我给出的查询相同。
      猜你喜欢
      • 2013-11-21
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 2016-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多