【问题标题】:Combining 2 SELECT queries组合 2 个 SELECT 查询
【发布时间】:2016-06-17 09:15:28
【问题描述】:

所以我有 2 个查询,我想将它们一起用于向用户生成一个输出结果。输出向用户描述了从 A 到 B 的旅程。当我尝试将第一个查询的结果连接到第二个查询时,我不断收到语法错误。

Query failed: ERROR: syntax error at or near "UNION" LINE 6: UNION ^

我看过一个类似的问题,但提供的解决方案和讨论似乎不起作用。

$name = pg_escape_string($_POST['name']); // Start destination from user input
$name2 = pg_escape_string($_POST['name2']); // End destination from user input

//If no results are given, the following query below will execute instead.

if (pg_num_rows($result) == 0 ) {

$query = "SELECT dt1.name as name1,dt1.time as time1,dt2.name as    name2,dt2.time as time2
From departure_times as dt1
inner join departure_times as dt2 on dt2.tram_id = dt1.tram_id

UNION 

SELECT dt1.name as name3,dt1.time as time3,dt2.name as name4,dt2.time as    time4
From departure_times as dt1
inner join departure_times as dt2 on dt2.tram_id = dt1.tram_id;

$result = pg_query($query) or die('Query failed: ' . pg_last_error());

} .....


The desired output I am looking for is the following :

      ------------------------------------------------------------------------
        name1 | time1  | name2  | time2 | name3 |  time3    | name4  | time4
      ------------------------------------------------------------------------

【问题讨论】:

  • 在每个子查询周围添加括号:(select ... limit 5) union (select ... limit 5)
  • 像这样:@Abelisto $query = ("SELECT dt1.name as name1,dt1.time as time1,dt2.name as name2,dt2.time as time2 从department_times 作为dt1 内部加入department_times 作为dt2 on dt2.tram_id = dt1.tram_id where dt1.name = '$name' and dt2.name = 'CitySquare' ) UNION (SELECT dt1.name as name3,dt1.time as time3,dt2.name as name4,dt2. time as time4 从department_times as dt1 内部加入department_times as dt2 on dt2.tram_id = dt1.tram_id where dt1.name = 'CitySquare' and dt2.name = '$name2' LIMIT 5");
  • 这仅显示列 name1、time1、name2、time2 而不是其余列。它正在获取数据,但我希望两个查询都位于不同的列中@Abelisto
  • UNION 垂直连接查询。要横向加入,请改用JOIN
  • 不要编辑你的问题,让它变得无用!

标签: php sql database postgresql


【解决方案1】:

从外观上看,您想要创建一个输出,列出从某个车站到城市广场的 5 辆有轨电车和从城市广场到另一个车站的 5 辆有轨电车。在这种情况下 - 你没有在这两件事之间建立任何联系(例如,准时) - 你应该加入一个伪列,row_number() OVER () 浮现在脑海中:

SELECT '$name' AS name1, w1.time1, 'City Square - arrival' AS name2, w1.time2,
       'City Square - departure' AS name3, w2.time3, '$name2' AS name4, w2.time4
FROM (
  SELECT dt1.time AS time1, dt2.time AS time2, row_number() OVER () AS rn
  FROM departure_times AS dt1
  JOIN departure_times AS dt2 USING (tram_id)
  WHERE dt1.name = '$name' AND dt2.name = 'CitySquare'
  LIMIT 5) w1
JOIN (
  SELECT dt1.time AS time3, dt2.time AS time4, row_number() OVER () AS rn
  FROM departure_times AS dt1
  JOIN departure_times AS dt2 USING (tram_id)
  WHERE dt1.name = 'CitySquare' AND dt2.name = '$name2'
  LIMIT 5) w2 USING (rn);

在每个子查询中,您选择感兴趣的五行。由于没有明显的属性你可以JOIN 这两组行,你必须创建一些可以达到这个目的的伪列(你需要一些东西来加入,否则你会得到一个CROSS JOIN 导致 5 x输出中的 5 行)。使用row_number() OVER () AS rn 就是这样做的:它创建一个别名为rn 的新列,其中包含整个行集的行号(OVER (),由于LIMIT 子句,5 行)。您在两个子查询中都执行此操作,以便可以将其用作连接条件:USING (rn)。您不必在输出中使用此列。

您无法控制将列出哪些 5 个电车时间。如果你想这样做,你应该在两个子查询中执行WHERE dt1 > CURRENT_TIMEORDER BY dt1 之类的操作,或者类似的操作。

【讨论】:

  • 您能否向我解释您提供的解决方案,以便我了解发生了什么,只是为了让事情清楚
  • @A.Khan 你一直试图删除我答案的重要部分。你不能那样做。一旦发布的东西会在 SO 上徘徊,直到版主或审阅者另有决定。没有人会允许您删除此类内容,所以您还不如放弃尝试。
【解决方案2】:

Abelisto 已经为您提供了第一部分,请在选择查询周围加上括号。

对于问题的第二部分,如果您希望显示所有列,那么您需要在两个查询中都有所有列。因此,类似于添加 null::text AS name3, null::timestamp AS time3 等的内容。(请注意,我猜测您使用类型转换的类型,您可能必须根据查询返回的类型进行更改。

【讨论】:

  • 这两个查询都为名称和时间返回一个字符变化类型,而时间没有时区类型。所以我需要添加 null::text AS name3, null::timestamp AS, time3 null::text AS name4, null::timestamp AS time4 以显示所有列。
猜你喜欢
  • 2010-11-10
  • 1970-01-01
  • 2015-01-26
  • 2018-08-02
  • 1970-01-01
  • 2013-08-13
  • 2011-09-27
  • 2020-10-01
相关资源
最近更新 更多