V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gzk329
V2EX  ›  数据库

[求助] 多条件查询怎么实现比较好?

  •  
  •   gzk329 · 2023-10-16 15:44:31 +08:00 · 1073 次点击
    这是一个创建于 402 天前的主题,其中的信息可能已经有所发展或是发生改变。

    数据库表中一个字段如下类型。

    [
    {"name":"conf1","value":"value1","type":"SYSTEM"},
    {"name":"conf2","value":"244","type":"SYSTEM"},
    {"name":"conf3","value":"value3","type":"SYSTEM"}
    ]
    
    来源是用户传入,conf1  value1  这些都是用户自定义。
    然后查询的时候,支持用户输入查询条件 ,一个查询条件 key value operator ,
    查询条件与查询条件之间关系为 AND 或 OR ,查询条件还得支持分组,组与组之间关系为 AND 或 OR
    
    给这个 json 的 name 属性加个索引?
    
    考虑查询效率,怎么实现比较好? 参数怎么设计比较好?
    
    
    还是我应该去 battle 一下,砍砍需求? 比如 AND 和 OR 砍掉变成 AND
    第 1 条附言  ·  2023-10-16 16:22:30 +08:00
    <select id="dynamicQuery" resultType="=ResultType">
        SELECT *
        FROM your_table
        WHERE id IN (
            <foreach item="item" collection="myList" open="" separator=" OR " close="">
                (
                    (item->>'name' = 'time' 
                    AND item->>'value' > '2023-10-16 00:00:00')
    
                    OR
    
                    (item->>'name' = 'status' 
                    AND item->>'value' = active')
                )
            </foreach>
        )
    </select>
    
    我研究了下,是可以做动态查询,前提是我要先把查询条件组装起来,但是那个查询组和查询条件之间的关系,搞得我参数很难结构化定义
    6 条回复    2023-10-16 17:13:09 +08:00
    oneisall8955
        1
    oneisall8955  
       2023-10-16 16:01:08 +08:00 via Android
    Gota
        2
    Gota  
       2023-10-16 16:07:43 +08:00
    不确定你用的是什么数据库。如果是关系型数据库,把用户自定义字段单分一张表存,而不是挤在一个 JSON 里,会不会比较容易查?
    abc0123xyz
        3
    abc0123xyz  
       2023-10-16 16:07:49 +08:00
    purensong
        4
    purensong  
       2023-10-16 16:18:44 +08:00
    直接一刀砍成单条件查询,多查几次
    zhangqian99
        5
    zhangqian99  
       2023-10-16 16:24:56 +08:00
    您需要实现复杂的查询逻辑,而且数据是用户自定义的,那么就需要设计一种比较灵活的数据结构和查询方式。在你的情况下,利用 MySQL 的 JSON 数据类型是一个合适的选择。MySQL 从 5.7.8 版本开始支持 JSON 数据类型,可以直接在 SQL 中进行 JSON 的查询和操作。

    首先,你的数据表可以设计为以下结构:

    ```sql
    CREATE TABLE Configurations (
    id INT AUTO_INCREMENT,
    data JSON,
    PRIMARY KEY (id)
    );
    ```

    在这个表中,`data`列是一个 JSON 类型,用于存储你的配置数据。

    然后,你可以为`data`列中的`name`属性创建一个虚拟列,并在这个虚拟列上创建索引,以提高查询效率:

    ```sql
    ALTER TABLE Configurations
    ADD COLUMN data_name AS (data->'$.name') VIRTUAL,
    ADD INDEX idx_data_name (data_name);
    ```

    查询时,你可以使用 MySQL 的 JSON 查询功能。例如,以下查询可以找到`name`为`conf1`的记录:

    ```sql
    SELECT *
    FROM Configurations
    WHERE data->'$.name' = 'conf1';
    ```

    对于更复杂的查询,你可能需要构造包含`AND`、`OR`和分组的 SQL 语句。为了实现这一点,你可能需要设计一个查询参数对象,该对象可以表示查询条件和它们的关系。以下是一个简单的设计:

    ```java
    public class QueryCondition {
    private String key;
    private String operator;
    private String value;
    private String relation; // AND or OR
    private List<QueryCondition> subConditions; // 用于存储分组条件
    }
    ```

    在这个设计中,`key`、`operator`和`value`用于表示一个查询条件。`relation`表示这个条件与下一个条件的关系(`AND`或`OR`)。`subConditions`是一个子查询条件列表,用于表示分组条件。

    你的查询方法可以接受一个`QueryCondition`列表作为参数,然后根据这个列表构造 SQL 语句。你需要遍历这个列表,并根据每个条件的`key`、`operator`、`value`和`relation`来构造 SQL 语句。对于`subConditions`,你可以使用递归方法来处理。

    注意,这是一个基础的设计,根据你的具体需求,可能需要进行一些修改和扩展。并且,请注意在构造 SQL 语句时防止 SQL 注入攻击,永远不要直接拼接用户输入的字符串。
    -------- powered by gpt-4 。(一个字都没改)
    zzmx
        6
    zzmx  
       2023-10-16 17:13:09 +08:00
    我就是 5 楼这种思路弄的,类名都一样 /doge ,支持表格任意字段、任意规则( eq 、like 、between 、in 等)查询。 分组我没弄
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3336 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 11:43 · PVG 19:43 · LAX 03:43 · JFK 06:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.