【问题标题】:Trying to Combine Values and Count in Multiple Fields in Same Table尝试在同一个表的多个字段中组合值和计数
【发布时间】:2014-07-06 19:23:33
【问题描述】:

我有一个成员列表数据库表(.MDB MS-Access,通过 ColdFusion 访问),其中包含四个电子邮件地址字段(email1、email 2、email3、email4)- ALL IN SAME TABLE。

我需要开发一个查询来生成所有电子邮件服务提供商域(例如 gmail.com、comcast.net 等)的列表以及每个域的数量,以及所有四个域的组合这些领域。期望的结果应该是一个看起来像这样的列表:

comcast.net (6)
gmail.com (14)
cs.com (1)
hotmail.com (4)
att.net (12)
aol.com (2)
 . . . . etc.

到目前为止,我可以为每个字段单独执行此操作,但是当我在所有四个字段中创建以下 UNION 查询查询时,我接近了我想要的,但它列出了每个人的总数字段而不是将它们相加。所以,我得到:

att.net (2)
att.net (3)
att.net (9)
att.net (13)
aol.com (6)
aol.com (4)
aol.com (1)
aol.com (8)
. . . etc.

而不是想要的:

att.net (27)
aol.com (19)
. . . etc.

我怎样才能让它们结合在一起?谢谢你的帮助!这是我的代码:

<!--- get list of ESP domain names (e.g. comcast.net) from members' email addresses --->
<!--- email address one --->
<cfquery name="cfqGetESP1" datasource="#member_datasource#">
SELECT MID(email1, INSTR(email1, '@') + 1)
AS esp
FROM tblMembers
WHERE email1 IS NOT NULL
</cfquery>
<!--- email address two --->
<cfquery name="cfqGetESP2" datasource="#member_datasource#">
SELECT MID(email2, INSTR(email2, '@') + 1)
AS esp
FROM tblMembers
WHERE email2 IS NOT NULL
</cfquery>
<!--- email address three --->
<cfquery name="cfqGetESP3" datasource="#member_datasource#">
SELECT MID(email3, INSTR(email3, '@') + 1)
AS esp
FROM tblMembers
WHERE email3 IS NOT NULL
</cfquery>
<!--- email address four --->
<cfquery name="cfqGetESP4" datasource="#member_datasource#">
SELECT MID(email4, INSTR(email4, '@') + 1)
AS esp
FROM tblMembers
WHERE email4 IS NOT NULL
</cfquery>

<!--- Query of Queries to get COMBINED total instances of EACH ESP --->
<!--- across ALL four email address fields --->
<cfquery name="cfqCountESP" dbtype="query">
    SELECT esp, COUNT(esp) AS instances
FROM cfqGetESP1
GROUP BY esp    
    UNION
SELECT esp, COUNT(esp) AS instances
FROM cfqGetESP2
GROUP BY esp
    UNION
SELECT esp, COUNT(esp) AS instances
FROM cfqGetESP3
GROUP BY esp    
    UNION
SELECT esp, COUNT(esp) AS instances
FROM cfqGetESP4
GROUP BY esp
ORDER BY esp ASC
</cfquery>

<!--- test display --->
<p>TEST DISPLAY COUNT ESP ACROSS ALL EMAIL ADDRESS FIELDS<br>
<cfoutput>
<cfloop query="cfqCountESP">
#cfqCountESP.esp# (#instances#)<br>
</cfloop>
</cfoutput>

【问题讨论】:

  • 这是 MS Access 的一大痛点。可以使用其他数据库吗?
  • 还可以考虑规范化电子邮件地址。如果地址存储在行中而不是列中,则此查询会简单得多:MemberEmail (Columns: MemberID, EmailAddress)。这种结构也更加灵活,允许每个成员根据需要发送尽可能多的电子邮件。

标签: sql ms-access coldfusion


【解决方案1】:

你应该可以替换这个查询:

SELECT esp, COUNT(esp) AS instances
FROM cfqGetESP1
GROUP BY esp    
    UNION
SELECT esp, COUNT(esp) AS instances
FROM cfqGetESP2
GROUP BY esp
    UNION
SELECT esp, COUNT(esp) AS instances
FROM cfqGetESP3
GROUP BY esp    
    UNION
SELECT esp, COUNT(esp) AS instances
FROM cfqGetESP4
GROUP BY esp
ORDER BY esp ASC

用这个:

SELECT esp, COUNT(*) AS Instances
FROM
(
    SELECT MID(email1, INSTR(email1, '@') + 1) AS esp
    FROM tblMembers
    WHERE email1 IS NOT NULL
    UNION ALL
    SELECT MID(email2, INSTR(email2, '@') + 1) AS esp
    FROM tblMembers
    WHERE email2 IS NOT NULL
    UNION ALL
    SELECT MID(email3, INSTR(email3, '@') + 1) AS esp
    FROM tblMembers
    WHERE email3 IS NOT NULL
    UNION ALL
    SELECT MID(email4, INSTR(email4, '@') + 1) AS esp
    FROM tblMembers
    WHERE email4 IS NOT NULL
) t
GROUP BY esp
ORDER BY esp

这会将基本的 UNION 查询包装到一个数据集中,然后将其聚合。 (我又去查询基表了,你可以很容易地对你建立的查询做同样的事情。)

顺便说一句,在这种情况下您不应该使用 UNION,而应使用 UNION ALL。 UNION 只会从整个联合数据集中取出不同的行。因此,如果您在电子邮件 1 中具有 att.net - 27 并且在电子邮件 2 中具有相同的统计信息,那么其中一行将丢失,并且您的聚合查询中将缺少 27 个实例。调试起来会非常令人沮丧,因为它有时只会弹出。 UNION ALL 将保留内部联合查询中的所有行。

【讨论】:

  • 我收到了一个 QoQ 语法错误“(。当我尝试使用 QoQ 时,所以我恢复到你所拥有的基表,它工作得很好!我是 SQL 的新手并且知道它必须是某种复合查询。我已经为此苦恼了好几天!非常感谢!
  • @user3784919:为了澄清起见,我看到你试图用你的 Cold Fusion 查询(这里不是 CF 人)做些什么,比如 cfqGetESP1。我以为你放在一起的那些查询是在 Access 中的。这就是你得到错误的原因。好的我明白了。是的,在这种情况下,必须回到基表。很高兴它对你有用。
  • @VBlades,ColdFusion 查询查询是一个方便的工具包,但有很多限制。例如,它没有 instr() 函数,也没有类似的东西。
  • @VBlades - 输出结果的另一个问题。例如,如果我运行以下命令来获取域“Comcast.net”的所有地址,我会从 WHERE 子句的一部分中得到一个语法错误,在该部分我想在“@”之后提取子字符串“comast.net”在电子邮件地址中。我该怎么做? (我对 MS-Access .MDB 表使用 ColdFusion - 不使用 MS-Access 应用程序本身。)谢谢!
  • 从 tblMembers 中选择 email_address,其中 email_address 不为空且 MID(email_address, INSTR(email_address, '@') + 1) = 'comcast.网'
猜你喜欢
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
相关资源
最近更新 更多