如何从多个mysql列中选择不同的值并将它们放在一个PHP数组中?

如何从多个mysql列中选择不同的值并将它们放在一个PHP数组中?,php,mysql,Php,Mysql,我有一个歌曲表,每首歌最多可以有3种不同的风格。所以在我的表格中,每首歌都有genre1、genre2和genre3列。我试图在列表中显示所有可用的类型 下面是一个随机示例集: genre1 genre2 genre3 metal jazz metal country pop oldies metal rap jazz hip-hop choir choir metal jazz 我希望列表,用php完成,以字母顺序显示可供选

我有一个歌曲表,每首歌最多可以有3种不同的风格。所以在我的表格中,每首歌都有genre1、genre2和genre3列。我试图在列表中显示所有可用的类型

下面是一个随机示例集:

genre1    genre2    genre3
metal     jazz
metal     country   pop
oldies    metal
rap
jazz      hip-hop   choir
choir     metal     jazz
我希望列表,用php完成,以字母顺序显示可供选择的不同类型。因此,它应该列出:

  • 唱诗班
  • 国家
  • 嘻哈
  • 爵士乐
  • 金属
  • 老歌
  • 流行音乐
  • 说唱

感谢所有的帮助。也许这不是最聪明的方法,但我想不出更好的方法。

从tabel中选择不同的genre1、genre2、genre3

也许你需要一个更好的数据库设计。。。
歌曲|流派|[song | id |流派| id]

那么单独的列就没有什么区别了?如果是这种情况,您可以使用
联合

SELECT genre1 AS g FROM t UNION SELECT genre2 AS g FROM t UNION SELECT genre3 AS g FROM t
如果有
WHERE
子句,则需要将其复制3次,或使用中间临时表

祝你好运


表:

mysql> SELECT genre1, genre2, genre3 FROM music;
+--------+---------+--------+
| genre1 | genre2  | genre3 |
+--------+---------+--------+
| metal  | jazz    |        | 
| metal  | country | pop    | 
| oldies | metal   |        | 
| rap    |         |        | 
| jazz   | hip-hop | choir  | 
| choir  | metal   | jazz   | 
+--------+---------+--------+
6 rows in set (0.00 sec)
分组:

mysql> SELECT genre1 AS g FROM music UNION ALL
          SELECT genre2 AS g FROM music UNION ALL
          SELECT genre3 AS g FROM music
+---------+
| g       |
+---------+
| metal   | 
| metal   | 
| oldies  | 
| rap     | 
| jazz    | 
| choir   | 
| jazz    | 
| country | 
| metal   | 
|         | 
| hip-hop | 
| metal   | 
|         | 
| pop     | 
|         | 
|         | 
| choir   | 
| jazz    | 
+---------+
18 rows in set (0.00 sec)
计数:

mysql> SELECT g, COUNT(*) AS c FROM
             (SELECT genre1 AS g FROM music UNION ALL
              SELECT genre2 AS g FROM music UNION ALL
              SELECT genre3 AS g FROM music)
       AS tg GROUP BY g;
+---------+---+
| g       | c |
+---------+---+
|         | 4 | 
| choir   | 2 | 
| country | 1 | 
| hip-hop | 1 | 
| jazz    | 3 | 
| metal   | 4 | 
| oldies  | 1 | 
| pop     | 1 | 
| rap     | 1 | 
+---------+---+
9 rows in set (0.01 sec)
假设这是一个数组,那么:

function coalesce_into_array($aggregate, $row) {
    foreach ($row as $genre) {
        $aggregate[] = $genre;
    }

    return $aggregate;
}

$data = array_unique(array_reduce($data, 'coalesce_into_array', array()));
sort($data);
但是,我不建议在严肃的应用程序中使用此选项。数据库设计很差。阅读有关数据库规范化的内容,了解如何改进数据库规范化。

除非出于性能原因将()流派分为三列,否则应该有一个与歌曲和流派相关的单独表格:

CREATE TABLE SongGenres (
    song INT NOT NULL REFERENCES Songs (id) ON DELETE CASCADE,
    genre VARCHAR(32) NOT NULL,
    UNIQUE INDEX (song, genre),
    INDEX genres (genre) -- improves performance for getting genre names
) Engine=InnoDB;
这就取消了要求(“Cross Road Blues”可以归入“Blues”和“Delta Blues”,但仅此而已)和人为限制(A3的乡村酸酸屋福音浮现在脑海中)每首歌三种风格的要求。如果您有一组有限的体裁,您可能希望创建体裁列。SongTyres表简化了获取所有流派的过程:

SELECT UNIQUE genre FROM SongGenres;
或者,您可以进一步规范化并为流派创建单独的表格:

CREATE TABLE Genres (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(32) NOT NULL,
    UNIQUE INDEX (name)
) Engine=InnoDB;

CREATE TABLE SongGenres (
    song INT NOT NULL REFERENCES Songs (id) ON DELETE CASCADE,
    genre INT NOT NULL REFERENCES Genres (id) ON DELETE RESTRICT,
    UNIQUE INDEX (song, genre)
) Engine=InnoDB;
这进一步简化了获取所有流派名称的过程(尽管这只是次要优势):

体裁表的一个主要优点是数据的正确性:如果有人拼错了体裁,它就不会出现在体裁表中。一个潜在的缺点是,它将有效类型限制为表中的类型。当然,给用户帐户提供歌曲类型的插入权限是有意义的,所以这个限制并不严重。一旦你开始添加新的体裁,你就会面临与没有体裁表时相同的问题:打字错误。与其添加“流派”表中未找到的新流派,不如查找类似的流派(例如,使用or),如果找到任何流派,请询问用户是否希望用找到的流派替换该流派或保留原始流派(并将其添加到流派列表)

以下是第一种情况下的数据(两个表,
歌曲
歌曲类型
):

mysql>从歌曲中选择*; +----+---------------------+--------+---- |id |头衔|艺术家|。。。 +----+---------------------+--------+---- |1 |十字路蓝调|。。。 |2 |山谷和平|。。。 +----+---------------------+--------+---- 一组2行(0.00秒) mysql>从歌曲类型中选择*; +------+-------------+ |歌曲类型| +------+-------------+ |2|酸| |1 |蓝色| |2 |国家| |1 |三角蓝| |2 |福音书| |2号楼| |2 |技术| +------+-------------+ 一组7行(0.00秒) mysql>从歌曲中选择s.title、sg.genre作为s,在s.id=sg.song上加入SongGenres作为sg; +---------------------+-------------+ |标题|体裁| +---------------------+-------------+ |十字路蓝调|蓝调| |Cross Road Blues | delta Blues| |山谷中的和平|酸| |山谷中的和平|国家| |山谷和平|福音| |山谷中的和平之家| |山谷和平|科技| +---------------------+-------------+ 一组7行(0.00秒) 使用单独的“流派”表,歌曲中的数据看起来是一样的,但在其他表中,我们会有如下内容:

mysql> SELECT * FROM Genres; +----+-------------+ | id | name | +----+-------------+ | 1 | acid | | 2 | blues | | 3 | classical | | 4 | country | | 5 | delta blues | | 6 | folk | | 7 | gospel | | 8 | hip-hop | | 9 | house | ... | 18 | techno | +----+-------------+ 18 rows in set (0.00 sec) mysql> SELECT * FROM SongGenres; +------+-------+ | song | genre | +------+-------+ | 1 | 2 | | 1 | 5 | | 2 | 1 | | 2 | 4 | | 2 | 7 | | 2 | 9 | | 2 | 18 | +------+-------+ 7 rows in set (0.00 sec) mysql> SELECT s.title, g.name AS genre -> FROM Songs AS s -> JOIN SongGenres AS sg ON s.id=sg.song -> JOIN Genres AS g ON sg.genre=g.id; +---------------------+-------------+ | title | genre | +---------------------+-------------+ | Cross Road Blues | blues | | Cross Road Blues | delta blues | | Peace In the Valley | acid | | Peace In the Valley | country | | Peace In the Valley | gospel | | Peace In the Valley | house | | Peace In the Valley | techno | +---------------------+-------------+ 7 rows in set (0.00 sec) mysql>从流派中选择*; +----+-------------+ |id |名称| +----+-------------+ |1 |酸| |2 |蓝色| |3 |经典| |4 |国家| |5 |三角蓝| |6 |民间| |7 |福音书| |8 |嘻哈| |9号楼| ... |18 |技术| +----+-------------+ 一组18行(0.00秒) mysql>从歌曲类型中选择*; +------+-------+ |歌曲类型| +------+-------+ | 1 | 2 | | 1 | 5 | | 2 | 1 | | 2 | 4 | | 2 | 7 | | 2 | 9 | | 2 | 18 | +------+-------+ 一组7行(0.00秒) mysql>选择s.title、g.name作为流派 ->从歌曲到音乐 ->在s.id=sg.song上以sg的身份加入歌曲类型 ->在sg上以g的形式加入流派。流派=g.id; +---------------------+-------------+ |标题|体裁| +---------------------+-------------+ |十字路蓝调|蓝调| |Cross Road Blues | delta Blues| |山谷中的和平|酸| |山谷中的和平|国家| |山谷和平|福音| |山谷中的和平之家| |山谷和平|科技| +---------------------+-------------+ 一组7行(0.00秒)
当数据从MySql输入时是什么样子的?它是一个数组吗?为了方便起见,您可以使用
UNION ALL
(速度更快),然后执行
选择g,从(
UNION here
)将(*)计算为c,并按g分组。这也会给你一个计数,你可以向用户展示你拥有更多的类型。所以当我获取数组时,所有的值都会在$row['g]中,对吗?谢谢我不确定我是否完全理解工会的所有版本。我该把工会放在哪里?我对订单没有把握
SELECT name FROM Genres;
mysql> SELECT * FROM Songs; +----+---------------------+--------+---- | id | title | artist | ... +----+---------------------+--------+---- | 1 | Cross Road Blues | ... | 2 | Peace In the Valley | ... +----+---------------------+--------+---- 2 rows in set (0.00 sec) mysql> SELECT * FROM SongGenres; +------+-------------+ | song | genre | +------+-------------+ | 2 | acid | | 1 | blues | | 2 | country | | 1 | delta blues | | 2 | gospel | | 2 | house | | 2 | techno | +------+-------------+ 7 rows in set (0.00 sec) mysql> SELECT s.title, sg.genre FROM Songs AS s JOIN SongGenres AS sg ON s.id=sg.song; +---------------------+-------------+ | title | genre | +---------------------+-------------+ | Cross Road Blues | blues | | Cross Road Blues | delta blues | | Peace In the Valley | acid | | Peace In the Valley | country | | Peace In the Valley | gospel | | Peace In the Valley | house | | Peace In the Valley | techno | +---------------------+-------------+ 7 rows in set (0.00 sec) mysql> SELECT * FROM Genres; +----+-------------+ | id | name | +----+-------------+ | 1 | acid | | 2 | blues | | 3 | classical | | 4 | country | | 5 | delta blues | | 6 | folk | | 7 | gospel | | 8 | hip-hop | | 9 | house | ... | 18 | techno | +----+-------------+ 18 rows in set (0.00 sec) mysql> SELECT * FROM SongGenres; +------+-------+ | song | genre | +------+-------+ | 1 | 2 | | 1 | 5 | | 2 | 1 | | 2 | 4 | | 2 | 7 | | 2 | 9 | | 2 | 18 | +------+-------+ 7 rows in set (0.00 sec) mysql> SELECT s.title, g.name AS genre -> FROM Songs AS s -> JOIN SongGenres AS sg ON s.id=sg.song -> JOIN Genres AS g ON sg.genre=g.id; +---------------------+-------------+ | title | genre | +---------------------+-------------+ | Cross Road Blues | blues | | Cross Road Blues | delta blues | | Peace In the Valley | acid | | Peace In the Valley | country | | Peace In the Valley | gospel | | Peace In the Valley | house | | Peace In the Valley | techno | +---------------------+-------------+ 7 rows in set (0.00 sec)