Php 如何从字段列表创建动态查询?

Php 如何从字段列表创建动态查询?,php,mysql,dynamicquery,Php,Mysql,Dynamicquery,我正在尝试使用PHP和MySQL构建一个动态查询 我所做的是创建了一个表(即字段\u关系) 此字段有5列 字段名称(字段“即帐户id、帐户名称…”的名称) 显示_标签(将字段替换为使用“即帐户Id、名称”的方式) 表_名称(此字段属于“即帐户”的表) 相关(字段与不同表“如果有”的关系。默认值为NULL) 相关的\u到\u字段(指向“如果有”的字段。默认值为NULL) 下面是一个示例数据 字段\u名称显示\u标签表\u名称相关\u到相关\u到\u字段 帐户\u id帐户id帐户NULL NUL

我正在尝试使用PHP和MySQL构建一个动态查询

我所做的是创建了一个表(即
字段\u关系
) 此字段有5列

  • 字段名称(字段“即帐户id、帐户名称…”的名称)
  • 显示_标签(将字段替换为使用“即帐户Id、名称”的方式)
  • 表_名称(此字段属于“即帐户”的表)
  • 相关(字段与不同表“如果有”的关系。默认值为
    NULL
  • 相关的\u到\u字段(指向“如果有”的字段。默认值为
    NULL
  • 下面是一个示例数据
    
    字段\u名称显示\u标签表\u名称相关\u到相关\u到\u字段
    帐户\u id帐户id帐户NULL NULL
    帐户名称帐户空
    名字名字名字联系人NULL NULL
    姓氏姓氏联系人NULL NULL
    联系人id联系人id联系人NULL NULL
    帐户id帐户id联系人帐户id
    任务id任务id任务NULL NULL
    主题任务NULL NULL
    分配给联系人的所有者\u id联系人\u id
    每日\u销售交易帐户\u id
    已售出交易的已售出金额NULL
    

    所以如果我用3秒钟创建一个HTML表单

  • 选择要显示的列
  • 将公式添加到列(可选)
  • 选择条件子句(可选)
  • “显示结果”按钮
  • 表单的第一部分将显示
    display\u label
    列中列出的所有值

    如果用户选择了名、名、姓

    然后查询将需要如下所示

    SELECT accounts.account_name, contacts.first_name, contacts.last_name
    FROM accounts 
    INNER JOIN contacts ON contacts.account_id = accounts.account_id
    
    SELECT accounts.account_name, SUM(daily_sales) AS daily_sales
    FROM accounts 
    LEFT JOIN sales ON sales.account_id = accounts.account_id
    WHERE sales.sold_on BETWEEN '2014-01-01 00:00:00' AND '2014-10-01 00:00:00'
    GROUP BY accounts.account_name
    
    查询完成后,将执行该查询

    或者,如果用户选择了“Name,Sales.”,则用户希望对列
    daily_Sales
    应用求和函数。最后,用户为“2014-01-01 00:00:00”和“2014-10-01 00:00:00”之间出售的
    选择了一个过滤器。

    然后查询将需要如下所示

    SELECT accounts.account_name, contacts.first_name, contacts.last_name
    FROM accounts 
    INNER JOIN contacts ON contacts.account_id = accounts.account_id
    
    SELECT accounts.account_name, SUM(daily_sales) AS daily_sales
    FROM accounts 
    LEFT JOIN sales ON sales.account_id = accounts.account_id
    WHERE sales.sold_on BETWEEN '2014-01-01 00:00:00' AND '2014-10-01 00:00:00'
    GROUP BY accounts.account_name
    
    查询完成后,将执行该查询

    如何生成这样的查询?我是否需要在
    字段关系表中添加更多列

    我并不担心如何构建PHP表单来捕获用户规范,但我正试图找出如何正确生成MySQL查询


    提前感谢您的帮助和时间。

    将构建sql查询视为一个简单的字符串构建练习。当您参考字段关系表时,上一页表单中发布的值将标识查询中需要的列和表

    第一个过帐值将标识其中一个表中的字段,告诉您需要FROM子句。然后,当您遇到第二个表中的字段时,它会告诉您添加一个 contacts.account\u id=accounts.account\u id子句上的内部联接联系人(或销售人员)。如果稍后遇到第三个表中的字段,则必须添加另一个JOIN子句


    在字段关系中,您根本不需要related_to和related_to_字段列,因为表单中发布的列名在引用字段关系表时会告诉您字段来自哪个表。

    首先,也许您最好查看几个ORM(对象关系管理)中的任何一个可用于PHP/MySQL的系统

    但是,如果你把轮子保持得很小(这意味着你只能解决非常简单的查询),那么重新发明轮子就相对容易了

    如果是这样的话,假设我们只需要内部联接,它们都是一对多类型的(实际上这不是一个严格的要求,我们将看到)。我们可以建立一个DIY ORM(我想更合适的名字应该是像‘DIY ORM Cthulhu Fhtagn’)

    第一步是将此信息存储在某个位置,例如数组。一个条目用于所有可能的联接。您还需要向系统描述您的表。您还可以让系统查询MySQL检索表和字段名,可能偶尔从生成PHP代码的单独实用程序中检索一次

    // This just maps what fields are in what tables
    $tables = array(
        'contacts' => array(
            'first_name' => true /* or an array of information such as SQL type, etc. */
        );
    );
    
    // This maps all the JOINs
    $orm = array(
        'contacts' => array(
            'accounts' => array(
                'on'    => array( 'account_id', 'account_id' ),
                'type'  => 'LEFT JOIN', //
            )
        )
    );
    
    因此,您可以从$selectFields列表开始。将这些字段复制到
    $unsolvedfields
    ,然后开始逐个检查它们。您的目标是解析所有字段

    伪代码(实际上并非如此伪):

    如果用户选择了姓名、名字、姓氏

    您还需要在人类可读的“名称”和“accounts.account\u Name”之间进行“翻译”。但是,一旦您这样做,上面的算法就会找到这些记录:

    Name        ... fields = [ accounts.account_name ], tables = [ accounts ], joins = [ ]
    First Name  ... fields = [ a.ac_name, co.first ], tables = [ ac, co ], joins = [ co ]
    Last Name   ... contacts is already in tables, so fields = [ 3 fields ], rest unchanged
    
    你为什么不用ORM呢? 在这种情况下,原则非常有用:


    您可以通过友好方式添加实体和字段,并将它们连接在一起:易于学习和实现。

    我不确定在动态使用内部连接与左连接时如何进行区分。此外,如何知道联接应位于此列contacts.account\u id=accounts.account\u id用户将不知道该关系。所以他们的想法是让这个工具找出关系。@Mike内部连接与左侧外部连接的信息不可用。根据该表中的数据我们不知道。@Mike,如果您定义了外键,您可以随时查看“信息”模式以智能地找出此类联接条件。至于Left vs INNER,您可以检查引用字段,看看它们是否可以为空。嗨,首先我要感谢您提供了大量信息。现在,据我所知,我需要获得一个包含以下两列的数组
    accounts.account\u name
    account name
    (我在