javascript - Node 使用 mysql 或 lodash 将多行合并为一行

标签 javascript mysql node.js express lodash

目前,我正在使用 Node MySQL在 Javascript 框架中实现 MySQL 查询的库。我有一个关于多行左连接的问题。当我左连接该表时,它返回多个对象,这是因为左连接将产生重复的行,但该特定属性的值不同。我现在想要实现的是,返回一个对象并将多个值插入到该特定属性的数组中。

表A

id | name | age
 1   abel   22
 2   john   22

表B

id | user_id | equip
 1      1      armor
 2      2      sword
 3      1      knife
 4      2      gun

查询

SELECT * FROM Table_A LEFT JOIN TABLE_B ON TABLE_B.user_id = TABLE_A.id;

现状

{
    id: 1
    name: abel
    age: 22
    user_id: 1
    equip: 'armor'
},
{
    id: 1
    name: abel
    age: 22
    user_id: 1
    equip: 'knife'
},
{
    id: 2
    name: john
    age: 22
    user_id: 2
    equip: 'sword'
},
{
    id: 2
    name: john
    age: 22
    user_id: 2
    equip: 'gun'
}

我想要实现的目标

{
    id: 1
    name: abel
    age: 22
    user_id: 1
    equip: [
       'armor','knife'
    ]
},
{
    id: 2
    name: john
    age: 22
    user_id: 2
    equip: [
       'sword','gun'
    ]
}

无论如何要使用 node mysql 来实现查询还是lodash?

最佳答案

您尝试做的事情无法通过联接来完成。以下是我的想法,尽管 SQL 向导可能有更好的解决方案:

SELECT Table_A.name, GROUP_CONCAT(item_name) AS equip
  FROM Table_B
JOIN Table_A
  ON Table_A.id=Table_B.person_id 
WHERE Table_A.id=1;

这会产生

+------+-------------------+
| name | person_items      |
+------+-------------------+
| abel | armor,sword,knife |
+------+-------------------+

然后只需使用 split(',') 创建一个数组。但我看到了一些超出你想要解决的问题。

Table_B 正在做太多工作。删除 user_id 列并创建第三个表 Table_A_Table_B,其中包含三列:id 主键、table_a_id 外键引用 Table_A.id 的键; table_b_id 外键引用 Table_B.id.

除非您以这种方式更改表,否则每次向表 B 添加行时都需要输入项目名称。通过在项目中创建/插入项目一次,消除这种冗余并正确使用关系数据库。自己的表,并在需要连接它们时使用子表来指向它和 Table_A 中的实体(即 Table_A_Table_B)。

名称需要更具描述性和准确性,例如。 Table_A -> peopleTable_B -> itemsTable_A_Table_B -> ' person_item,装备->item_name`。

从第一个方面开始:

CREATE TABLE people (
  id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50),
  age INT UNSIGNED
);

CREATE TABLE items (
  id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
  item_name VARCHAR(20)
);

CREATE TABLE person_item (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  person_id INT UNSIGNED NOT NULL,
  item_id INT UNSIGNED NOT NULL,

  PRIMARY KEY (id),
  FOREIGN KEY (person_id) 
    REFERENCES people(id)
    ON UPDATE CASCADE ON DELETE CASCADE,
  FOREIGN KEY (item_id)
    REFERENCES items(id)
    ON UPDATE CASCADE ON DELETE CASCADE
);

混合一些数据:

INSERT INTO people (name, age) VALUES ('abel', 20), ('john', 21);
INSERT INTO items (item_name) VALUES ('armor'), ('sword'), ('knife');
INSERT INTO person_item (person_id, item_id) VALUES (1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3);

MySQL 不支持数组,我认为,您想要做的事情的最佳实践是根本不这样做,而是这样做:

SELECT p.*, i.* 
  FROM people p 
JOIN person_item pi 
  ON p.id=pi.person_id 
JOIN items i 
  ON i.id=pi.item_id 
WHERE p.id=1;

这会产生:

+------+-----+-----------+
| name | age | item_name |
+------+-----+-----------+
| abel |  22 | armor     |
| abel |  22 | sword     |
| abel |  22 | knife     |
+------+-----+-----------+

然后您可以使用 Node 来获取您想要的数据。或者你可以这样做:

SET sql_mode='';

SELECT people.name, GROUP_CONCAT(item_name) AS person_items
  FROM items 
JOIN person_item 
  ON person_item.item_id=items.id 
JOIN people 
  ON people.id=person_item.person_id 
WHERE people.id=1;

制作:

+------+-------------------+
| name | person_items      |
+------+-------------------+
| abel | armor,sword,knife |
+------+-------------------+

关于javascript - Node 使用 mysql 或 lodash 将多行合并为一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44223629/

相关文章:

javascript - Node 异步/等待与 promise.all

javascript - 通用类型(T)与 typescript 中的任何类型之间有什么区别

javascript - 在 jQuery 中按字母分隔未排序的列表?

php - Chrome 中页面刷新时 MySQL 查询运行两次

mysql - 将 MySQL 连接到 Talend 时出错

python - 准备一个复杂的 python 项目以提交到启动板

javascript - 如何在完成一个功能后调用不同的功能?

javascript - 如何向我的导航链接 React 路由器添加事件类?

javascript - 如何在 phonegap 的 ios7 之上添加永久线路

mysql - MySQL 更新查询中观察到突然下降