【问题标题】:How to get unique pairs from two columns in SQL如何从 SQL 中的两列中获取唯一对
【发布时间】:2017-08-08 09:44:14
【问题描述】:

我被困在http://www.sql-ex.ru/learn_exercises.php#answer_ref 的练习 68 上。

数据库由这四个表组成:

  1. 公司(ID_comp,名称)
  2. Trip(trip_no, id_comp, plane, town_from, town_to, time_out, time_in)
  3. 乘客(ID_psg,姓名)
  4. Pass_in_trip(trip_no, date, ID_psg, place)

练习的目的是: 找出航班(旅行)数量最多的路线数量。 笔记。

  1. A - B 和 B - A 将被视为相同的路线。
  2. 仅使用 Trip 表。

我可以得到“找出具有最多航班(旅行)数量的路线数量”的正确答案,但在考虑注释 1 时不能得到正确答案:A - B 和 B - A 将被视为 SAME 路线。

我不知道如何获得唯一对: 如果我们有输出:

| town_from | town_to   | count |
| --------- | --------- | ----- |
| London    | Singapore | 4     |
| Singapore | London    | 4     |

我如何选择以便它只给我

| town_from | town_to   | count |
| --------- | --------- | ----- |
| London    | Singapore | 4     |

我能够通过以下查询完成问题:

与 x AS( SELECT con, sum(c) as s FROM( SELECT town_from, town_to, 'con' = CASE WHEN lower(town_from)

从 x 中选择计数 (*) WHERE s = (SELECT max(s) FROM x)

【问题讨论】:

  • 您使用的是什么数据库? MySQL 还是 SQL Server?请正确标记。
  • 请发布产生您当前输出的尝试查询。

标签: mysql sql tsql


【解决方案1】:
select a.town_from, a.town_to, count(a.plane) ta from (
select plane, 
(case when town_from < town_to then town_from else town_to end) as town_from, 
(case when town_from < town_to then town_to else town_from end) as town_to 
from trip) as a
group by a.town_from, a.town_to
having count(a.plane) >= all (select count(plane) from trip group by plane, town_from, town_to)) s```

【讨论】:

    【解决方案2】:

    您需要以表示 from->to 的方式与表示 to->from 的方式相同来查看 Trip 表。执行此操作的典型方法是确保始终对 town_from &lt;(=) town_to 进行排序。

    一般来说,以下查询将以这种方式投影Trip。 case 子句来回切换以保持它们始终排序:

    select trip_no, id_comp, plane, 
        case when town_from < town_to then town_from else town_to end as town_from, 
        case when town_from < town_to then town_to else town_from end as town_to, 
        time_out, time_in
    from Trip
    

    然后您可以在查询中从此投影中进行选择:

    select ...
    from (
        select trip_no, id_comp, plane, 
            case when town_from < town_to then town_from else town_to end as town_from, 
            case when town_from < town_to then town_to else town_from end as town_to, 
            time_out, time_in
        from Trip
    ) as x
    

    为了解决这个特殊问题,我们可以应用相同的逻辑,但删除不必要的列(优化器无论如何都应该这样做,但在人眼看来它看起来更干净):

    select town_from, town_to, count(*)
    from (
        select 
            case when town_from < town_to then town_from else town_to end as town_from, 
            case when town_from < town_to then town_to else town_from end as town_to 
        from Trip
    ) as x
    group by town_from, town_to
    

    注意:如果我错了,请纠正我,但在您的预期输出中,伦敦新加坡的总数应该是 8,而不是 4。您在一个方向有 4 次行程,在另一个方向有 4 次行程,总共 8 次。

    然后我们可以使用相同的查询来查找最大数量的航班,然后找到具有该数量的路线,然后进行计数。我怀疑你已经把这部分记下来了,但这留作练习。

    【讨论】:

    • 在附录中,基本上逻辑是根据字母顺序切换位置字段,然后将其作为基表。
    • @lc。这正是我想要的!感谢您的解释。我想出了一种方法来通过使用 case 语句连接 town_from 和 town_to 来回答这个问题,但是你的例子更干净,也是我想要的。再次感谢。我赞成你的回答,但我的代表太低了:D。
    猜你喜欢
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 2022-06-22
    • 1970-01-01
    • 1970-01-01
    • 2022-12-14
    相关资源
    最近更新 更多