【问题标题】:How to create a sequence on selected values in MySQL?如何在 MySQL 中的选定值上创建序列?
【发布时间】:2015-05-19 21:18:31
【问题描述】:

我正在尝试创建一个查询,该查询将从声明的变量中选择一个团队,然后通过为其余团队提供通用品牌和顺序 ID 来使其余团队“匿名”。

例如,如果我的数据集有 3 个不同的团队名称(ABC、DEF 和 GHI),但我只希望显示 1 个所选团队 (ABC) 的真实值。这是我正在使用的查询的框架:

SET @teamid = 123;

SELECT     CASE WHEN ID = @teamid
                THEN NAME
                ELSE 'Team' + ' - ' + SEQ
                END AS 'Team Name',
           SUM(TOTAL) AS 'Team Total'
FROM       TEAM
GROUP BY   1;

我希望结果看起来像这样:

 Team Name:    Team Total:
 ABC           100
 Team - 1      50
 Team - 2      150

如何创建一个查询,该查询将创建一个可以替换原始团队名称的唯一编号?我知道我必须替换 case 语句的“SEQ”部分,但我不确定用什么来替换它。此外,无论是否匿名,每个团队都具有相同的 ID 很重要(因此,如果团队 DEF 有 50 行,则应仅显示为 Team - 1 而不是 Team - 1-50),以便我的分组将正常工作。

感谢您的帮助。

【问题讨论】:

  • @MattBusche 这是针对 SQL-Server,而不是 MySQL。
  • ROWNUM()...有趣,还没有考虑过使用它。这将有助于获得一个唯一的 ID,但我更希望能够提供一种更简化的方法。我可能可以制作一个临时表并重新加入 Team 表,并基本上改变我上面的 CASE 语句以使用 ROWNUM(),但无论如何要使用顺序类型的过程来消除该步骤。无论哪种方式,感谢您的回应。
  • @dupton MySQL 没有 ROWNUM。该答案适用于 SQL-Server,而不是 MySQL。

标签: mysql sequence case-statement nextval


【解决方案1】:

使用您递增的用户定义变量。此外,MySQL 使用CONCAT 连接字符串,而不是+

SET @teamid = 123;

SELECT     CASE WHEN ID = @teamid
                THEN NAME
                ELSE CONCAT('Team  - ', @SEQ)
                END AS 'Team Name',
           SUM(TOTAL) AS 'Team Total',
           @SEQ := CASE WHEN ID = @teamid 
                        THEN @SEQ
                        ELSE @SEQ + 1
                   END
FROM       TEAM
CROSS JOIN (SELECT @SEQ := 1) AS vars
GROUP BY   ID;

DEMO

【讨论】:

  • 谢谢巴马尔。也注意到您对 ROWNUM() 的评论。你的演示看起来很棒(以前从未见过那个网站,真的很酷),但是当我在我的 MySQL 实例上尝试它时,我返回了团队名称和 SEQ 列的 BLOB(我删除了团队总计只是为了摆脱一些杂乱无章)。知道为什么会发生这种情况吗?
  • @SEQ 列可以忽略,它只是查询内部需要的。不过,我不确定为什么你会得到团队名称的 blob。 NAME 的数据类型是什么?
  • name的数据类型是varchar(50)。如果我不希望它包含在数据中,我将如何在 Team Total 之后隐藏/忽略 SEQ 部分?对不起,如果这是一个愚蠢的问题,这对我来说很新。
  • 你可以把它放在一个子查询中,然后外层查询只能选择Team TotalTeam Name这两个列。
  • 上面提到@SEQ 的转换修复了 BLOB 问题,与此查询相同。谢谢巴尔玛。
【解决方案2】:

这应该可以。内部查询通过仅在名称更改时递增计数器来为团队名称命名。外层使用这些名称进行分组。

SET @teamid := [the id you want];
SET @prevName := "";
SET @team_i := 0;

SELECT `Team Name`, SUM(TOTAL) AS `Team Total`
FROM (
   SELECT @team_i := @team_i + IF(@prevName <>NAME, 1, 0) AS `teamIndex`
      , @prevName := NAME AS `OriginalName`
      , IF(ID = @teamid, NAME, CONCAT('Team  - ', @team_i)) AS `Team Name`
      , TOTAL
   FROM TEAM
   ORDER BY NAME) AS subQ
GROUP BY `Team Name`;

实际上,它可以可能被反转(这可能会稍微快一些,尽管最终结果中确实会出现额外的字段):

SET @teamid := [the id you want];
SET @prevName := "";
SET @team_i := 0;

SELECT @team_i := @team_i + IF(@prevName <>NAME, 1, 0) AS `teamIndex`
      , @prevName := NAME AS `OriginalName`
      , IF(ID = @teamid, NAME, CONCAT('Team  - ', @team_i)) AS `Team Name`
      , `Team Total`
FROM (
   SELECT `NAME`, SUM(TOTAL) AS `Team Total`
   FROM TEAM
   GROUP BY NAME) AS subQ
ORDER BY `NAME`;

【讨论】:

  • 这看起来也是一个不错的方法,但我面临的问题与 Bamar 的建议相同,即输出显示为 BLOB。关于为什么会发生这种情况的任何想法? Team Name 数据类型是 varchar(50),我尝试将其转换为 char,但没有骰子。
  • 所以看起来我可以通过将变量转换为 CHAR(50) 来解决 BLOB 问题,而且效果很好。谢谢朋友!
猜你喜欢
  • 2014-12-22
  • 2011-08-14
  • 2020-02-25
  • 2016-11-18
  • 1970-01-01
  • 1970-01-01
  • 2023-02-23
  • 1970-01-01
相关资源
最近更新 更多