【问题标题】:How to ORDER BY in SQL UNION of JOINED tables not showing ordered columns in result如何在 JOINED 表的 SQL UNION 中 ORDER BY 未在结果中显示有序列
【发布时间】:2020-08-23 14:51:38
【问题描述】:

我正在尝试获取两个连接结果将被联合并按几列排序的表。我发现在每个联合选择中都必须提到排序的列。但我不希望有序列出现在结果中。可能吗?也许还有其他方法可以获得我想要的结果。

这是我的查询:

SELECT coupon_id,
       coupon_name,
       real_price,
       discount_price,
       difference_percent,
       discount_percent,
       payment_price,
       photo,
       company_id,
       company_name
FROM
  (SELECT cpn.id AS coupon_id,
          cpn.name_ru AS coupon_name,
          cpn.real_price,
          cpn.discount_price,
          cpn.difference_percent,
          cpn.discount_percent,
          cpn.payment_price,
          cp.photo,
          com.id company_id,
          com.name_ru AS company_name
   FROM coupon cpn
   LEFT JOIN coupon_photo cp ON cpn.id = cp.coupon_id
   LEFT JOIN company com ON cpn.company_id = com.id
   WHERE cpn.id NOT IN
       (SELECT coupon_id AS id
        FROM transaction
        WHERE Date_add(created_time, interval 10 MINUTE) > Now()
          AND status = 'pending')
     AND cpn.exp_date > Now()
     AND cpn.valid_date > Now()
     AND cpn.available > 0
   UNION SELECT cpn.id AS coupon_id,
                cpn.name_ru AS coupon_name,
                cpn.real_price,
                cpn.discount_price,
                cpn.difference_percent,
                cpn.discount_percent,
                cpn.payment_price,
                cp.photo,
                com.id company_id,
                com.name_ru AS company_name
   FROM coupon cpn
   LEFT JOIN coupon_photo cp ON cpn.id = cp.coupon_id
   LEFT JOIN company com ON cpn.company_id = com.id
   LEFT JOIN transaction trans ON cpn.id = trans.coupon_id
   WHERE cpn.exp_date > Now()
     AND cpn.valid_date > Now()
     AND Date_add(trans.created_time, interval 10 MINUTE) > NOW()
     AND trans.status = 'pending'
     AND (cpn.available - trans.amount) > 0 GROUP  BY cpn.id) results
ORDER BY cpn.advertised DESC,
         cpn.sold DESC,
         cpn.views DESC

【问题讨论】:

  • 您自己尝试解决什么问题(简单的问题!)?
  • 我已经查看了所有与这个问题相似的问题。我尝试分别订购两个选择,但没有给出预期的结果。
  • 将排序所需的列添加到联合的每个成员的 SELECT 子句中。这并不意味着您还必须将它们添加到主查询的 SELECT 子句中;保持 that 不变,但添加子查询。
  • 嗯,在大多数情况下,按不可见列排序是没有用的。除非您解释,否则结果看起来是无序的。

标签: mysql sql mariadb


【解决方案1】:

您的results 子查询不包含您尝试order by 的列。您需要将它们添加到联合的两个部分。您不必将它们添加到您的选择中,但它们需要出现在子查询中,以便您可以在 ORDER BY 中使用它们。

SELECT coupon_id,
       coupon_name,
       real_price,
       discount_price,
       difference_percent,
       discount_percent,
       payment_price,
       photo,
       company_id,
       company_name
FROM
  (SELECT cpn.id AS coupon_id,
          cpn.name_ru AS coupon_name,
          cpn.real_price,
          cpn.discount_price,
          cpn.difference_percent,
          cpn.discount_percent,
          cpn.payment_price,
          cp.photo,
          cpn.advertised,
          cpn.sold,
          cpn.views,
          com.id company_id,
          com.name_ru AS company_name
   FROM coupon cpn
   LEFT JOIN coupon_photo cp ON cpn.id = cp.coupon_id
   LEFT JOIN company com ON cpn.company_id = com.id
   WHERE cpn.id NOT IN
       (SELECT coupon_id AS id
        FROM transaction
        WHERE Date_add(created_time, interval 10 MINUTE) > Now()
          AND status = 'pending')
     AND cpn.exp_date > Now()
     AND cpn.valid_date > Now()
     AND cpn.available > 0
   UNION SELECT cpn.id AS coupon_id,
                cpn.name_ru AS coupon_name,
                cpn.real_price,
                cpn.discount_price,
                cpn.difference_percent,
                cpn.discount_percent,
                cpn.payment_price,
                cp.photo,
                cpn.advertised,
                cpn.sold,
                cpn.views,
                com.id company_id,
                com.name_ru AS company_name
   FROM coupon cpn
   LEFT JOIN coupon_photo cp ON cpn.id = cp.coupon_id
   LEFT JOIN company com ON cpn.company_id = com.id
   LEFT JOIN transaction trans ON cpn.id = trans.coupon_id
   WHERE cpn.exp_date > Now()
     AND cpn.valid_date > Now()
     AND Date_add(trans.created_time, interval 10 MINUTE) > NOW()
     AND trans.status = 'pending'
     AND (cpn.available - trans.amount) > 0 GROUP  BY cpn.id) results
ORDER BY advertised DESC,
         sold DESC,
         views DESC

正如 Strawberry 所指出的,当您不聚合任何内容时,使用 GROUP BY 并不是最佳实践。在这种情况下,由于 MySQL 使用 ANY_VALUE(),它可能会导致意外结果。它返回 GROUP BY 组中某行的值。它返回哪一行是不确定的。这意味着它完全取决于 MySQL 服务器。

我假设您使用它来避免重复行。您应该找到另一种重复数据删除方法。

此外,执行 LEFT JOIN 然后过滤 JOIN 右侧的元素与执行 INNER JOIN 相同。只需确保这与您要实现的目标一致即可。

【讨论】:

  • 公平地说,OP 说他们知道这个问题,所以不确定你在这里实际取得了什么
  • LEFT JOIN x...WHERE x </>/=...INNER JOIN x... 相同
  • ...而且,在没有任何聚合函数的情况下,GROUP BY 子句永远不合适
  • @RiggsFolly OP 担心他必须显示列,他不必选择列但列需要存在于表中(在我们的例子中是子查询),以便他可以订购由他们
  • 所以将有用的信息添加到答案中,这将使答案对 OP 和其他任何来阅读您的答案的人来说更有价值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-26
  • 2010-10-04
  • 2010-09-17
相关资源
最近更新 更多