【问题标题】:get unique available combination获得唯一的可用组合
【发布时间】:2022-01-18 10:09:41
【问题描述】:

我正在尝试解决以下问题,我需要在数据集中获得可用的唯一组合

这是包含两列的输入表

IND, USA
USA, IND
AUS, IND
IND, AUS
UAE, AUS

使用了这个查询

SELECT DISTINCT
       LEAST(c1, c2) AS c1,
       GREATEST(c1, c2) AS c2
FROM   table_name

得到输出

IND, USA
AUS, IND
AUS, UAE

输出中的前两条记录很好,但第三条不正确,因为输入数据中甚至不存在AUS, UAE 组合。

我可以知道如何在我的查询中解决这个问题吗?

预期输出

IND, USA
AUS, IND
UAE, AUS

【问题讨论】:

  • 这是一张有两列 C1 和 C2 的表吗?
  • 如果你不关心是 [IND, USA] 还是 [USA, IND],你为什么要关心 [AUS,UAE] 与 [UAE, AUS]?
  • @Littlefoot Well AUS,UAE 实际上并未出现在原始表格中。
  • 我知道,@Tim :) 只是问。对您编写的代码没有异议,+1。

标签: sql oracle


【解决方案1】:

使用ROW_NUMBER()

WITH cte AS (
    SELECT t.*, ROW_NUMBER() OVER (PARTITION BY LEAST(c1, c2), GREATEST(c1, c2)
                                   ORDER BY c1) rn
    FROM table_name t
)

SELECT c1, c2
FROM cte
WHERE rn = 1;

这里的策略是为具有相同国家值对的每组记录分配一个行号。我们报告具有“较早”的第一个国家/地区的单对。

【讨论】:

  • 我们不能不使用最小和最大吗?
  • @OxanaGrey 好吧,您可以将 LEASTGREATEST 调用替换为 CASE 表达式。
【解决方案2】:

intercept 与 reverse except 的联合可以得到你。

create table table_name (c1 char(3), c2 char(3));
insert into table_name values
  ('IND' , 'USA') 
, ('USA' , 'IND') 
, ('AUS' , 'IND') 
, ('IND' , 'AUS') 
, ('UAE' , 'AUS');

(SELECT DISTINCT 
  LEAST(c1, c2) AS c1, 
  GREATEST(c1, c2) AS c2
FROM table_name 
intersect
SELECT c1, c2 from table_name) 
union
(SELECT DISTINCT 
  GREATEST(c1, c2) AS c1, 
  LEAST(c1, c2) AS c2
FROM table_name 
except
SELECT c2, c1 from table_name)
ORDER BY c2 DESC
c1 c2
IND USA
AUS IND
UAE AUS

db小提琴here

【讨论】:

  • 它的猎物很酷,但我无法理解此查询中用于达到输出的逻辑思维。请问在回答问题之前您的逻辑想法是什么?
  • 我的意思是说,你对数据进行洗牌并采用选择性数据集来获得输出背后的逻辑思想是什么?
  • 真的很简单。 1)我怎样才能单独获得奇怪的球(阿联酋,澳大利亚),因此除外。 2)如何在没有反向古怪的情况下获得其他人,因此是INTERSECT。公平地说,我的第一直觉是像 Tim 一样使用 row_number。但是添加一个与另一个过于相似的解决方案有点蹩脚。所以我不得不使用其他的 sql 工具来解决这个难题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 1970-01-01
  • 1970-01-01
  • 2022-11-17
  • 2011-10-11
相关资源
最近更新 更多