【问题标题】:mysql : How make recurring fields appear only once?mysql:如何使重复字段只出现一次?
【发布时间】:2014-01-27 09:47:29
【问题描述】:

我有 sql 创建和插入脚本:

CREATE TABLE NINJA_TYPE (
   NINJA_TYPE_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
   DESCRIPTION varchar(30) NOT NULL,
   PRIMARY KEY (NINJA_TYPE_ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO NINJA_TYPE VALUES (1, 'Genin');
INSERT INTO NINJA_TYPE VALUES (2, 'Chunin');
INSERT INTO NINJA_TYPE VALUES (3, 'Jounin');
INSERT INTO NINJA_TYPE VALUES (4, 'Kage');

CREATE TABLE NINJA (
   NINJA_ID int(10) unsigned NOT NULL AUTO_INCREMENT,
   NINJA_TYPE_ID int(10) unsigned NOT NULL,
   NAME varchar(30) NOT NULL,
   PRIMARY KEY (NINJA_ID),
   KEY FK_NINJA_TYPE (NINJA_TYPE_ID),
   CONSTRAINT FK_NINJA_TYPE FOREIGN KEY (NINJA_TYPE_ID) REFERENCES NINJA_TYPE (NINJA_TYPE_ID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


INSERT INTO NINJA VALUES (1, 1, 'Fransie');
INSERT INTO NINJA VALUES (2, 1, 'Mary Grace');
INSERT INTO NINJA VALUES (3, 1, 'Hannah');
INSERT INTO NINJA VALUES (4, 1, 'Chinita');
INSERT INTO NINJA VALUES (5, 2, 'Nookie');
INSERT INTO NINJA VALUES (6, 2, 'Ruth');
INSERT INTO NINJA VALUES (7, 2, 'Rose');
INSERT INTO NINJA VALUES (8, 2, 'Irish');
INSERT INTO NINJA VALUES (9, 3, 'Tokmol');
INSERT INTO NINJA VALUES (10, 3, 'JG');
INSERT INTO NINJA VALUES (11, 3, 'JM');
INSERT INTO NINJA VALUES (12, 3, 'Jose');
INSERT INTO NINJA VALUES (13, 4, 'Tom');
INSERT INTO NINJA VALUES (14, 4, 'Johan');
INSERT INTO NINJA VALUES (15, 4, 'Christian');
INSERT INTO NINJA VALUES (16, 4, 'Lemuel');

我有 sql 选择:

SELECT DISTINCT NAME, DESCRIPTION FROM NINJA N 
INNER JOIN NINJA_TYPE NT ON N.NINJA_TYPE_ID = NT.NINJA_TYPE_ID ;

结果:

+------------+-------------+
| NAME       | DESCRIPTION |
+------------+-------------+
| Fransie    | Genin       |
| Mary Grace | Genin       |
| Hannah     | Genin       |
| Chinita    | Genin       |
| Nookie     | Chunin      |
| Ruth       | Chunin      |
| Rose       | Chunin      |
| Irish      | Chunin      |
| Tokmol     | Jounin      |
| JG         | Jounin      |
| JM         | Jounin      |
| Jose       | Jounin      |
| Tom        | Kage        |
| Johan      | Kage        |
| Christian  | Kage        |
| Lemuel     | Kage        |
+------------+-------------+

我也试过 group by:

SELECT DISTINCT NAME, DESCRIPTION FROM NINJA N 
INNER JOIN NINJA_TYPE NT ON N.NINJA_TYPE_ID = NT.NINJA_TYPE_ID GROUP BY DESCRIPTION;

结果:

+---------+-------------+
| NAME    | DESCRIPTION |
+---------+-------------+
| Nookie  | Chunin      |
| Fransie | Genin       |
| Tokmol  | Jounin      |
| Tom     | Kage        |
+---------+-------------+

我想要发生的是:

+------------+-------------+
| NAME       | DESCRIPTION |
+------------+-------------+
| Fransie    | Genin       |
| Mary Grace |             |
| Hannah     |             |
| Chinita    |             |
| Nookie     | Chunin      |
| Ruth       |             |
| Rose       |             |
| Irish      |             |
| Tokmol     | Jounin      |
| JG         |             |
| JM         |             |
| Jose       |             |
| Tom        | Kage        |
| Johan      |             |
| Christian  |             |
| Lemuel     |             |
+------------+-------------+

请不要问我为什么要这样做。我有一个理由。我只是想知道如何处理它。请帮忙。

PS:我今天可能无法回答一些试探性的问题,因为我必须去某个地方,明天再回来。请随时给出答案、cmets 和建议。

谢谢。

【问题讨论】:

  • 通常你在你的应用程序代码中这样做,SQL不是用来呈现数据的。

标签: mysql sql select


【解决方案1】:

那就这样吧:

SELECT
  dist.name,
  IF(grouped.description IS NULL, '', grouped.description) AS description
FROM
(SELECT 
  DISTINCT NAME, 
  DESCRIPTION 
FROM 
  NINJA AS N 
    INNER JOIN NINJA_TYPE AS NT 
      ON N.NINJA_TYPE_ID = NT.NINJA_TYPE_ID) AS dist
LEFT JOIN
(SELECT 
   DISTINCT NAME, 
   DESCRIPTION 
 FROM 
   NINJA AS N 
     INNER JOIN NINJA_TYPE AS NT 
       ON N.NINJA_TYPE_ID = NT.NINJA_TYPE_ID 
 GROUP BY 
   DESCRIPTION) AS grouped
ON 
  dist.name=grouped.name

-你会看到和expected 一样的结果。请注意,出于格式化目的,使用应用程序后处理是更好的主意。

【讨论】:

  • 非常感谢。它按预期工作。我知道它在应用程序方面做得更好,但我认为如果在本机 SQL 中完成它会更有效,因为我不必做额外的处理。
【解决方案2】:

虽然我完全同意米海的观点,但你也可以做这样的事情......

SELECT * FROM users;
+----+----------+-----------+
| id | name     | surname   |
+----+----------+-----------+
|  1 | John     | Lennon    |
|  2 | Paul     | McCartney |
|  3 | George   | Harrison  |
|  4 | Ringo    | Starr     |
|  5 | Yoko Ono | Lennon    |
|  6 | Linda    | McCartney |
|  7 | Olivia   | Harrison  |
|  8 | Barbara  | Bach      |
|  9 | Stella   | McCartney |
+----+----------+-----------+

SELECT u.name
     , IF(u.surname=@last,'',@last:=u.surname) surname
  FROM users u, (SELECT @last='')x
 ORDER 
    BY u.surname;
+----------+-----------+
| name     | surname   |
+----------+-----------+
| Barbara  | Bach      |
| George   | Harrison  |
| Olivia   |           |
| John     | Lennon    |
| Yoko Ono |           |
| Paul     | McCartney |
| Linda    |           |
| Stella   |           |
| Ringo    | Starr     |
+----------+-----------+

【讨论】:

    【解决方案3】:

    这个简单的呢?

    SELECT
      nt.DESCRIPTION, GROUP_CONCAT(n.name) names
    FROM
      NINJA_TYPE nt
    JOIN
      NINJA n
        ON n.NINJA_TYPE_ID = nt.NINJA_TYPE_ID
    GROUP BY
      nt.NINJA_TYPE_ID;
    
    +-------------+-----------------------------------+
    | DESCRIPTION | names                             |
    +-------------+-----------------------------------+
    | Genin       | Fransie,Mary Grace,Hannah,Chinita |
    | Chunin      | Nookie,Ruth,Rose,Irish            |
    | Jounin      | Tokmol,JG,JM,Jose                 |
    | Kage        | Tom,Johan,Christian,Lemuel        |
    +-------------+-----------------------------------+
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-01
      • 1970-01-01
      相关资源
      最近更新 更多