如何将这些 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 语句中的主要内容,如果未能解决你的问题,请参考以下文章

SQL中如何将两个相同的表格组合成一个表格

将嵌套查询转换为 sql 视图

是否可以在 SQL 中合并到 SELECT 中?

合并两个查询以获取 SQL 中的合并值

SQL 在 Select 语句中合并两列

mysql多表查询合并到一个临时表,怎么再加一列并把各自的表名加上?