如何将这些 SQL SELECT 查询合并到一个 SELECT 语句中
Posted
技术标签:
【中文标题】如何将这些 SQL SELECT 查询合并到一个 SELECT 语句中【英文标题】:How do I Combine these SQL SELECT queries into one SELECT statement 【发布时间】:2011-01-23 09:42:56 【问题描述】:如何将这两个 select 语句合并到一个查询中:
SELECT SUM( incidents ) AS fires, neighborhoods AS fire_neighborhoods
FROM (
SELECT *
FROM `fires_2009_incident_location`
UNION ALL SELECT *
FROM `fires_2008_incident_location`
UNION ALL SELECT *
FROM `fires_2007_incident_location`
UNION ALL SELECT *
FROM `fires_2006_incident_location`
) AS combo
GROUP BY fire_neighborhoods ORDER BY fires DESC
SELECT SUM( incidents ) AS adw, neighborhoods AS adw_neighborhoods
FROM (
SELECT *
FROM `adw_2009_incident_location`
UNION ALL SELECT *
FROM `adw_2008_incident_location`
UNION ALL SELECT *
FROM `adw_2007_incident_location`
UNION ALL SELECT *
FROM `adw_2006_incident_location`
) AS combo2
GROUP BY adw_neighborhoods ORDER BY adw DESC
所以,我希望查询返回,例如:
fire_neighborhoods fires adw_neighborhoods adw
xyzNeighborhood 6 abcNeighborhood 22
jklNeighborhood 3 tuvNeighborhood 40
我想简单地结合上面两个查询的结果。这两个查询是相互独立的。一个查询的结果不会影响另一个查询的结果。我只需要一种方法将两个结果合二为一。
如果有人有任何建议,请告诉我。
谢谢。
-拉克西米迪
【问题讨论】:
我一定错过了什么。为什么不能将这两个查询联合起来? 你能把你的表的结构贴出来吗? 为什么人们要投票赞成这个问题?这个问题真的有用吗?这对我来说似乎相当学术和多余。 @Jim G.:责备选民徽章:***.com/badges/155/electorate 为什么架构每年映射一个表?这些是视图吗? 【参考方案1】:您给出的示例表明您希望水平组合查询,但后来您表示它们是完全独立的。这些是相互矛盾的陈述,因为当记录确实相互关联时,您通常会水平组合数据。下面是我将它们水平组合的想法,但我也记下我在其下方垂直组合它们的想法。
这取决于您希望如何将它们链接起来。如果是基于邻域查询,可以在 fire_neighborhoods = adw_neighborhoods 上的两个较大的查询之间做一个 join,例如:
SELECT fire_neighborhoods, fires, adw
FROM (
SELECT SUM( incidents ) AS fires, neighborhoods AS fire_neighborhoods
FROM (
SELECT *
FROM `fires_2009_incident_location`
UNION ALL SELECT *
FROM `fires_2008_incident_location`
UNION ALL SELECT *
FROM `fires_2007_incident_location`
UNION ALL SELECT *
FROM `fires_2006_incident_location`
) AS combo
GROUP BY fire_neighborhoods ORDER BY fires DESC
) AS fires
INNER JOIN (
SELECT SUM( incidents ) AS adw, neighborhoods AS adw_neighborhoods
FROM (
SELECT *
FROM `adw_2009_incident_location`
UNION ALL SELECT *
FROM `adw_2008_incident_location`
UNION ALL SELECT *
FROM `adw_2007_incident_location`
UNION ALL SELECT *
FROM `adw_2006_incident_location`
) AS combo2
GROUP BY adw_neighborhoods ORDER BY adw DESC
) AS adw
ON fires.fire_neighborhoods = adw.adw_neighborhoods
这只是一个例子。您可能需要不同的连接或其他东西才能使其适合您。
现在,您说这两个查询是独立的,不会相互影响。如果它们确实没有共同点,您应该在每个查询中添加一列,指示它来自哪个查询(例如,为 fire 查询添加一个常量值为 1 的列,为 adw 添加一个常量值为 2 的列询问)。然后,只需将两个大查询联合起来。这将以垂直方式而不是水平方式组合它们。
【讨论】:
您好 NYSystemsAnalyst,感谢您提出添加带有常量的列的建议。我可能最终会这样做。 -Laxmidi【参考方案2】:如果我正确理解您的需求,您可以将查询合并在一起,添加一列让您知道它来自哪个查询:
SELECT SUM( incidents ) AS fires_or_adw, neighborhoods AS fire_or_adw_neighborhoods, 'Fires' as which_query
FROM (
SELECT *
FROM `fires_2009_incident_location`
UNION ALL SELECT *
FROM `fires_2008_incident_location`
UNION ALL SELECT *
FROM `fires_2007_incident_location`
UNION ALL SELECT *
FROM `fires_2006_incident_location`
) AS combo
GROUP BY fire_neighborhoods ORDER BY fires DESC
UNION
SELECT SUM( incidents ) AS fires_or_adw, neighborhoods AS fire_or_adw_neighborhoods, 'ADW' as which_query
FROM (
SELECT *
FROM `adw_2009_incident_location`
UNION ALL SELECT *
FROM `adw_2008_incident_location`
UNION ALL SELECT *
FROM `adw_2007_incident_location`
UNION ALL SELECT *
FROM `adw_2006_incident_location`
) AS combo2
GROUP BY adw_neighborhoods ORDER BY adw DESC
当然,您将拥有两倍的行数,并且一半的数据将为空,但只是像您的示例中那样将结果“猛击”在一起并不常见。
【讨论】:
嗨亚伦,我想我不需要水平返回数据。我可以添加一个列来指示它是火灾还是 adw,然后让其他列是社区和事件。 -Laxmidi 嗨 Aaron,我在上一条信息中忘记说“谢谢”。对不起。 -Laxmidi【参考方案3】:其他人给出的使用鉴别器列的答案看起来像您所追求的,但以防万一,可以将虚拟占位符列添加到联合中,如下所示:
SELECT
SUM( incidents ) AS fires,
neighborhoods AS fire_neighborhoods,
0 as adw,
'' as adw_neighbourhoods
FROM (
SELECT *
FROM `fires_2009_incident_location`
UNION ALL SELECT *
FROM `fires_2008_incident_location`
UNION ALL SELECT *
FROM `fires_2007_incident_location`
UNION ALL SELECT *
FROM `fires_2006_incident_location`
) AS combo
GROUP BY fire_neighborhoods ORDER BY fires DESC
UNION
SELECT
0 as fires,
'' as fire_neighbourhoods,
SUM( incidents ) AS adw,
neighborhoods AS adw_neighborhoods
FROM (
SELECT *
FROM `adw_2009_incident_location`
UNION ALL SELECT *
FROM `adw_2008_incident_location`
UNION ALL SELECT *
FROM `adw_2007_incident_location`
UNION ALL SELECT *
FROM `adw_2006_incident_location`
) AS combo2
GROUP BY adw_neighborhoods ORDER BY adw DESC
【讨论】:
嗨,大卫,感谢您的留言。我尝试了您的建议,但不幸的是,我无法让它发挥作用。是否可以在 mysql 中添加虚拟列? -Laxmidi @Laxmidi - 您在运行该语法时是否看到错误?我不确定 mySQL,但我希望它应该可以工作。旅游问题被某人重新标记为 tsql,这是 microsoft sql 实现,我现在要重新标记它。【参考方案4】:感谢您帮助解决这个问题。向 David Hall、Aaron、Jeffrey Whitledge 和 NYSystemsAnalyst 致敬。我选择了虚拟列选项:
SELECT SUM( incidents ) , neighborhoods, 'adw' as offense
FROM (
SELECT *
FROM `adw_2009_incident_location`
UNION ALL SELECT *
FROM `adw_2008_incident_location`
UNION ALL SELECT *
FROM `adw_2007_incident_location`
UNION ALL SELECT *
FROM `adw_2006_incident_location`
) AS combo
GROUP BY neighborhoods
UNION ALL
SELECT SUM( incidents ), neighborhoods, 'fire' as offense
FROM (
SELECT *
FROM `fire_2009_incident_location`
UNION ALL SELECT *
FROM `fire_2008_incident_location`
UNION ALL SELECT *
FROM `fire_2007_incident_location`
UNION ALL SELECT *
FROM `fire_2006_incident_location`
) AS combo2
GROUP BY neighborhoods
【讨论】:
【参考方案5】:并排显示两个不相关的查询通常是报告软件的工作,而不是 SQL 引擎的工作。这里的问题是您要求查询工具做一些它不适合做的事情:显示格式。
关系(从根本上说,这是 SELECT 的结果应该是的)是一种数据结构,它对世界的状态进行断言。每一行都定义了一系列(理想情况下)正确的命题。
在您的问题中,这些行包含相互不相关且无法陈述任何命题的事实的任意连接。
【讨论】:
嗨,杰弗里,你是对的。水平返回数据没有意义。谢谢-Laxmidi以上是关于如何将这些 SQL SELECT 查询合并到一个 SELECT 语句中的主要内容,如果未能解决你的问题,请参考以下文章