如何在以下条件下为 4 个表编写 JOIN QUERY

Posted

技术标签:

【中文标题】如何在以下条件下为 4 个表编写 JOIN QUERY【英文标题】:How to write JOIN QUERY for 4 tables in the below condition 【发布时间】: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 

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

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

【问题讨论】:

【参考方案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】:

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

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

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

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

【讨论】:

这与我给出的查询相同。

以上是关于如何在以下条件下为 4 个表编写 JOIN QUERY的主要内容,如果未能解决你的问题,请参考以下文章

3 个表和 2 个带有 CONCAT 表达式的独立 JOIN

如何创建有条件的 LEFT JOIN?

无法在 Nhb 4 中构建 2 个表 JOIN,仅包含某些字段可供选择

带有OR条件的FULL OUTER JOIN

26.MySQL中的内连接INNER JOIN

如何在MySQL高效的join3个表