MySQL n部分查询1-n关系

时间:2019-10-19 09:14:52

标签: mysql node.js

(几天前才开始学习SQL,如果这是一个愚蠢的问题,请对不起!)

我有三个表,用户,地址和地址类别。每个用户都有多个地址,但每个AddressCategory最多只能有1个地址。我想做一个查询,根据每个AddressCategory的不同标准搜索“用户”。

表结构如下:

用户:

id
1
2

地址类别:

category
HomeAddress
WorkAddress

地址:

userId   category     address
1        HomeAddress  1 Washington Street
1        WorkAddress  53 Elm Avenue
2        HomeAddress  7 Bernard Street

假设我要搜索所有家庭住址中包含“街道”一词且工作地址中包含“大道”一词的用户。我可以使用查询:

SELECT * FROM Users 
INNER JOIN Addresses a1 ON Users.id=a1.userId
INNER JOIN Addresses a2 ON Users.id=a2.userId
WHERE a1.category='HomeAddress' AND a1.address LIKE '%Street%'
AND a2.category='WorkAddress' AND a2.address LIKE '%Avenue%'

如果要在任意数量的AddressCategories中进行查询,则可以使用上述相同的原理动态构建查询:

// dictionary of query parts
var q_parts = {HomeAddress: 'Street',
                WorkAddress: 'Avenue'
                ...}

// build the query string piece by piece
let q_str1="", q_str2="";
let i=0;
for (q in q_parts) {
    i++;
    q_str1 += "INNER JOIN Addresses a${i} ON Users.id=a${1}.userId ";
    q_str2 += (i==1) ? "WHERE " : "AND ";
    q_str2 += "a${i}.category='${q}' AND a${i}.address LIKE '%${q_parts[q]}%' ";
}

// complete query string
let q_str = "SELECT * FROM Users "+q_str1+q_str2;

我现在的工作方式可以使用,但是构建查询字符串很容易出错,并且随着类别数量的增加,最终字符串很快变得巨大。似乎必须有更好的方法。在MySQL中执行此类查询的正确方法是什么? (或者我的表格组织方式有问题吗?)

1 个答案:

答案 0 :(得分:0)

您可以将其用于查询构建。
官方网站:https://knexjs.org/
Npm链接:https://www.npmjs.com/package/knex

一个示例SQL不必多次连接。它未经测试,只是一个想法。 您可以使用When/then中的Where clause进行个案验证。最后,根据用户的总类别(分组依据)进行过滤。

SELECT *
FROM
Users Inner Join
  (SELECT userId,
          count(category) AS categoryCount
   WHERE address LIKE '%Street%' LIKE CASE
                                          WHEN category = 'HomeAddress' THEN '%Street%'
                                          WHEN category = 'WorkAddress' THEN '%Avenue%'
                                      END
   GROUP BY userId) a ON Users.id = a.userId 
WHERE categoryCount = ? -- inject your count of all categories here, maybe get from another query