MySQL Select, 单列唯一

MySQL Select, unique in one column

假设我有一个 table 具有以下 rows/values:

我需要一种方法来 select 数量中的值,但如果它们重复则只需要一次。因此,从这个例子中,我想 select A、B 和 C 一次。 SQL 结果应该如下所示:

您可以根据需要使用不同的功能处理此类情况:

案例 1 : 如果每个名称具有相同的值:

select distinct name, amount from [table name]

案例 2 : 您有重复项,每个名称的值都不同,您想要选择值最高的那个。如果您需要最少的人出现,请使用 min()

select name, max(amount) from [table name] group by 1

案例 3: 你需要的那个,剩下的重复部分有空白。

  • 行号将根据金额的值创建行,并且由于值相同,因此将逐步创建它,然后您可以使用 IF 创建一个新列 where rank_ > 1 then blanks。这也将涵盖您希望 select 只是最小值然后为其余名称值留空的情况
    With ranking as (
    
    select 
    *,
    ROW_NUMBER() OVER(PARTITION BY NAME ORDER BY AMOUNT) AS RANK_    
     from [table]
    )
    SELECT
    *,
    IF(RANK_ > 1,"",AMOUNT) AS NEW_AMOUNT
    FROM ranking

情况4:你需要select最大,其他名字留空

  • 您只需将 order by clause of ROW_NUMBER() 调整为 DESC。这将使排名 1 达到每个名称的最高金额,其余的将填充空白
    With ranking as (
    
    select 
    *,
    ROW_NUMBER() OVER(PARTITION BY NAME ORDER BY AMOUNT DESC) AS RANK_
     from [table]
    )
    
    SELECT
    *,
    IF(RANK_ > 1,"",AMOUNT) AS NEW_AMOUNT
    FROM ranking

使用 LAG() 函数并将名称的先前金额与当前行金额进行比较。

-- MySQL (v5.8)
SELECT t.name
     , CASE WHEN t.amount = t.prev_val THEN '' ELSE amount END amount
FROM (SELECT *
           , LAG(amount) OVER (PARTITION BY name ORDER BY name) prev_val
      FROM test) t

请从urlhttps://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=8c1af9afcadf2849a85ad045df7ed580

检查

如果您使用的是 mysql 8,则可以使用 row_number

with x as (
  select *, row_number() over(partition by name order by amount) rn
  from t
)
select name, case when rn=1 then amount else '' end amount
from x

example Fiddle

其他答案遗漏了一个非常重要的点:A SQL table returns 一个 unordered 集,除非有明确的 order by.

您提供的数据包含完全重复的行。出于这个原因,我认为最好的方法是在外部查询中使用 row_number() order by:

select name, (case when seqnum = 1 then amount end) as amount
from (select t.*,
             row_number() over (partition by name, amount) as seqnum
      from t
     ) t
order by name, seqnum;

请注意 MySQL 不需要 row_number()order by 参数。

不过,更常见的是,您会有一些其他列(例如日期或 ID)用于订购。我还应该强调,这种类型的格式化通常在应用层处理,而不是在数据库中处理。