如何在以下条件下为 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 xx
和 count 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