【问题标题】:MySql UNION SELECT is missing fieldsMySql UNION SELECT 缺少字段
【发布时间】:2016-02-12 15:53:11
【问题描述】:

我越来越沮丧,因为我不明白为什么在我的带有 UNION 的 SELECT 中我缺少一些字段。 我阅读了有关这方面的良好文档,并遵循了最常见的示例,以避免在第一个和第二个 SELECT 之间获得不同的列数。

它包括在两个语句之间添加 NULL 列,达到偶数列。

这是我的情况:

$query = "(SELECT GC.GroupNO AS GroupNO,
    GC.Name AS Name,
    GC.Pax AS Pax,
    GC.Start AS Start,
    NULL AS custid,
    NULL AS firstname,
    NULL AS lastname,
    NULL AS arrivaldate,
    NULL AS hour,
    NULL AS pax,
    NULL AS cctype,
    NULL AS created,
    NULL AS sid,
    NULL AS ref_source,
    NULL AS numnights
  FROM LargeGroupHostels, GroupContacts AS GC
   WHERE LargeGroupHostels.HostelNumber = %d
   AND LargeGroupHostels.Status = %s
   AND LargeGroupHostels.GroupNO = GC.GroupNO";
   AND GC.Start < %s
   ORDER BY LastUpdated DESC LIMIT %d, %d
   )UNION(
    SELECT
    NULL AS GroupNO,
    NULL AS Name,
    NULL AS Pax,
    NULL AS Start,
    `custid`,
    `firstname`,
    `lastname`,
    `arrivaldate`,
    `hour`,
    `pax`,
    `cctype`,
    `created`,
    `sid`,
    `ref_source`,
    datediff(departdate, arrivaldate) AS numnights
    FROM customer_details
    WHERE hostelnumber = %d
    AND lastupdated = "" AND status != "CANX"
    AND booking_type IN ("HOSTEL", "HOSTELPACK")
    ORDER BY customer_details.arrivaldate, customer_details.created
    LIMIT %d, %d )
    ';

除了我知道要做的一些优化和一些更改之外,我的问题是: - 为什么我没有得到GC.Name,GC.Pax,GC.Start 的列?如果我反转这两个 SELECT,它会发生完全相反的情况,只考虑 GC.Name,GC.Pax,GC.Start 并避免其他列。

我对这种查询不太习惯,这是我第一次处理这个问题。我确定我错过了什么,但我不明白是什么

【问题讨论】:

  • 我可能在这里遗漏了一些东西 - 但是你为什么要使用联合呢?联合用于具有相同数据结构的多个查询。这看起来像您正在将旅馆数据与客户数据合并到单个结果中,这可以通过任何类型的连接来完成,并且可能会产生更具可读性的结果
  • 第一个查询有groupno,第二个查询有numnights,他们没有排队。
  • @KaiQing 你有理由,但在这种情况下,记录将排列在一个数组中,因为即使名称可能暗示不同,它们也有很多共同点。问题是我得到了一个非常大的数组,同时我需要对结果进行分页以提高性能。我曾尝试使用 array_slice 进行分页,但加载记录的问题当然仍然存在
  • 查询需要多动态?您可以低效地处理数据并将结果缓存在纯文本中,或者查看更复杂的存储过程,但我真的不能就此提出建议。没有什么比静态更快或更高效的了

标签: mysql union mysql-error-1222


【解决方案1】:

您正在尝试将 GC.nameName 合并。这些被 MySQL 解释为两个单独的列,因为它无法智能地猜测您的意图(并且可能不应该具有这种能力)。您应该为第一个 SELECT 语句中当前没有别名的列名设置别名,如下所示:

SELECT GC.GroupNO AS GroupNO,
GC.Name AS Name,
GC.Pax AS Pax,
GC.Start AS Start,

在所有其他情况下,您的别名或原始列名匹配。

我也同意上述其中一个 cmets 的观点,即这可能更适合某种 JOIN。

【讨论】:

  • 确实如此,但我也尝试了该解决方案,但它不起作用。我已按照您的建议更新了原始问题中的查询
  • @RobertoRizzi 那么你现在得到了什么结果?如果两个 SELECT 语句中的列完全匹配,我看不出你会如何“丢失”列。
  • 好吧,var 转储 GroupNO 或 Pax,例如我得到 NULL,相反,var dumping custid 它显示正确:(
  • @RobertoRizzi 您将在每一行的某些字段上获得 NULL 值。您是在两个 SELECT 语句中设计引入的。我认为您的问题是联合中缺少列,现在看来您的问题可能与底层子查询返回的意外结果有关。您能否至少确认通过此更改,您将获得结果集中您期望的所有列?
  • @RobertoRizzi 那将是一个完全不同的问题。一个更复杂的一个和一个可能需要您显示有关数据库架构的更多信息、来自相关表的示例数据以及所需结果集的示例和说明。如果您在通过 JOIN 完成这一切时遇到问题,您应该考虑将其作为一个不同的问题打开,这就是您听起来想要做的事情。如果我们已经解决了缺失列的问题,您至少应该接受一个答案并结束该问题,因为它对未来的读者仍有可能的价值。
【解决方案2】:

好像列的位置不一样

$query = "(SELECT GC.GroupNO,
GC.Name,
 .....
NULL AS ref_source
FROM LargeGroupHostels, GroupContacts AS GC

SELECT
   NULL AS Name,

  ....

  datediff(departdate, arrivaldate) as numnights
  FROM customer_details

在第一列中的第一个选择中,第二个选择中不存在一列,在第二个选择中,最后的列与第一个选择不匹配

【讨论】:

  • 感谢您的回复。我已按照您的建议修复了查询,但它一直没有记录GC.GroupNO, GC.Name, GC.Pax,GC.Start
  • 您在第一个选择中加入,但我没有看到 on 子句 ..FROM LargeGroupHostels, GroupContacts AS GC ....是对的 ..?
  • 列排序对 UNION 没有影响。
  • @scaisEdge 是的,这是它需要的改进之一。连接在 WHERE 子句中 `AND LargeGroupHostels.GroupNO = GC.GroupNO`
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-08
  • 2016-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多