如何从多个mysql列中选择不同的值并将它们放在一个PHP数组中?
我有一个歌曲表,每首歌最多可以有3种不同的风格。所以在我的表格中,每首歌都有genre1、genre2和genre3列。我试图在列表中显示所有可用的类型 下面是一个随机示例集:如何从多个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完成,以字母顺序显示可供选
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)