如何对数组中的特定字段进行分组?

Posted

技术标签:

【中文标题】如何对数组中的特定字段进行分组?【英文标题】:How to group a specific field in array? 【发布时间】:2018-06-04 12:15:41 【问题描述】:

我需要获得一个团队赢得的trophies,每个奖杯都是在一个特定赛季的比赛中获得的,但是一个团队可以在不同赛季赢得同一比赛的奖杯。

我编写了一个从数据库中提取奖杯的查询:

$sql = $this->db->prepare("SELECT t.*, s.*, c.*,
    t.team_id as team_id,
    s.id as season_id,
    s.name as season_name,
    c.id as competition_id,
    c.name as competition_name
    FROM team_trophies t
    INNER JOIN competition_seasons s ON s.id = t.season_id
    INNER JOIN competition c ON c.id = s.competition_id
    WHERE team_id = :team_id
  ");

基本上我从team_trophies 表中为特定球队选择了所有trophies 并加入competition_seasons 以检索奖杯的赛季详细信息,competition 表相同。

这行得通,我明白了:

[
    
        "team_id": "23291",
        "season_id": "2",
        "position": "Winner",
        "wins": "4",
        "id": "1093",
        "competition_id": "1093",
        "name": "Premier League",
        "update_at": "2018-06-04 12:12:30",
        "country_id": "1",
        "category": "1",
        "season_name": "2017",
        "competition_name": "Premier League"
    ,
    
        "team_id": "23291",
        "season_id": "3",
        "position": "Runner-up",
        "wins": "1",
        "id": "1093",
        "competition_id": "1093",
        "name": "Premier League",
        "update_at": "2018-06-04 12:14:39",
        "country_id": "1",
        "category": "1",
        "season_name": "2015",
        "competition_name": "Premier League"
    
]

但我会返回这样的结果:

[
    
        "team_id": "23291",
        "position": "Winner",
        "wins": "4",
        "id": "1093",
        "competition_id": "1093",
        "name": "Premier League",
        "update_at": "2018-06-04 12:12:30",
        "country_id": "1",
        "category": "1",
        "seasons": [
                           ["season_name":"2017", "season_id":"2"],
                           ["season_name":"2015", "season_id":"3"],
                       ]
        "competition_name": "Premier League"
    
]

如您所见,我在结果中有一行包含该奖杯的seasons 作为array,这更具可读性并避免冗余。

可以使用sql 来实现吗?或者我需要使用php 解决?

谢谢。

更新 - 表结构

CREATE TABLE IF NOT EXISTS `swp`.`competition` (
  `id` INT NOT NULL,
  `name` VARCHAR(255) NULL,
  PRIMARY KEY (`id`),
  ENGINE = InnoDB;


 CREATE TABLE IF NOT EXISTS `swp`.`competition_seasons` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `competition_id` INT NOT NULL,
  `season_id` INT NULL,
  `name` VARCHAR(45) NOT NULL,
  `update_at` DATETIME NULL,
  PRIMARY KEY (`id`),
  INDEX `FK_competition_competition_seasons_competition_id_idx` (`competition_id` ASC),
  CONSTRAINT `FK_competition_competition_seasons_competition_id`
    FOREIGN KEY (`competition_id`)
    REFERENCES `swp`.`competition` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


CREATE TABLE IF NOT EXISTS `swp`.`team_trophies` (
  `team_id` INT NOT NULL,
  `season_id` INT NOT NULL,
  `position` VARCHAR(255) NOT NULL,
  `wins` INT NOT NULL,
  INDEX `FK_team_team_trophies_team_id_idx` (`team_id` ASC),
  INDEX `FK_season_team_trophies_season_id_idx` (`season_id` ASC),
  CONSTRAINT `FK_team_team_trophies_team_id`
    FOREIGN KEY (`team_id`)
    REFERENCES `swp`.`team` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `FK_season_team_trophies_season_id`
    FOREIGN KEY (`season_id`)
    REFERENCES `swp`.`competition_seasons` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- Some INSERTs

INSERT INTO `team_trophies` (`team_id`, `season_id`, `position`, `wins` VALUES (23291, 2, 'Winner', 4), (23291, 3, 'Runner-up', 1);


INSERT INTO `competition`  (`id`, `country_id`, `name`, `category`) VALUES (1093, 1, 'Premier League', 1);

INSERT INTO `competition_seasons` (`id`, `competition_id`, `season_id`, 
`name`, `update_at`) VALUES
(1, 1093, 14963, '2018', '2018-06-04 12:10:28'),
(2, 1093, 13198, '2017', '2018-06-04 12:12:30');

【问题讨论】:

不应该season_id 也是一个数组(以及大多数其他属性)? 不理解 JSON,因为它不是逻辑的... 2015 年不是 team 23291 的 season_id 2 那么你为什么想要那个 JSON 输出。 @Charanoglu 所以,现在我们很困惑。结果应该是什么样子? 那么update_at、position等呢? 示例数据与 JSON 结构匹配什么? 【参考方案1】:

感谢一位名叫 Ghost 的大师,这是一个将一维数组转换为多维数组的简单示例......

<?php

$my_array = array();
$my_array =
array
(
    0 => array
        (
            id => '4',
            project_id => '2289',
            task => 'Drawing'
        ),

    1 => array
        (
            id => '5',
            project_id => '2289',
            task => 'Surveying'
        ),

    2 => array
        (
            id => '6',
            project_id => '2289',
            task => 'Meeting'
        ),

    3 => array
        (
            id => '1',
            project_id => '2282',
            task => 'Folding'
        ),

    4 => array
        (
            id => '2',
            project_id => '2282',
            task => 'Printing'
        ),

    5 => array
        (
            id => '3',
            project_id => '2282',
            task => 'Cutting'
        )

);

$new_array = array();
foreach ($my_array as $row) 
   $new_array[$row['project_id']]['project_id'] = $row['project_id'];
   $new_array[$row['project_id']]['task'][] = $row['task'];


$new_array = array_values($new_array); // reindex
// removes `$row['project_id']` on each group

print_r($new_array);

?>

输出:

Array
(
    [0] => Array
        (
            [project_id] => 2289
            [task] => Array
                (
                    [0] => Drawing
                    [1] => Surveying
                    [2] => Meeting
                )

        )

    [1] => Array
        (
            [project_id] => 2282
            [task] => Array
                (
                    [0] => Folding
                    [1] => Printing
                    [2] => Cutting
                )

        )

)

【讨论】:

@charangolu 很遗憾,您的数据集和结果集之间的转置难以理解,所以我不确定我们能否提供进一步的帮助。 你不会告诉我们选择的逻辑。如何、为什么会忽略 1 胜和亚军等?

以上是关于如何对数组中的特定字段进行分组?的主要内容,如果未能解决你的问题,请参考以下文章

如何按特定的子数组值对多维数组进行分组?

如何对 MongoDB 中数组内的字段值进行分组?

如何按月对数组中的值进行分组?

如何对 BigQuery 中的重复字段进行分组

如何对数组中的日期进行分组?

如何根据反应中的状态属性对数组中的元素进行分组?