【问题标题】:Make search query using KVP return results when some search attributes are not supplied未提供某些搜索属性时,使用 KVP 返回结果进行搜索查询
【发布时间】:2022-01-22 20:35:40
【问题描述】:

我需要有关成功运行的复杂 SQL 查询的帮助,但需要验证一个额外的步骤才能提供可靠的结果。

这些是此查询中涉及的主要 3 个表:

RULE
rule_id   rule_set_name   status   position   date_from   date_to
1         B2C             1        1          null        null
2         England All     1        2          null        null


RULE_ATTRIBUTE
attribute_id   attribute_code
1              customer_group
2              customer
3              country
4              subdivision_one
5              subdivision_two

RULE_ATTRIBUTE_VALUE
value_id   attribute_id   store_id   rule_id   value   parent_group_id   parent_country_id   parent_subdivision_1_id
9          1              0          2         0       null              null                null
10         1              0          2         1       null              null                null
11         1              0          2         2       null              null                null
12         1              0          2         3       null              null                null
13         1              0          2         4       null              null                null
14         1              0          2         8       null              null                null
15         1              0          2         9       null              null                null
16         3              0          2         34      null              null                null
17         4              0          2         540     null              34                  null
18         1              0          1         0       null              null                null
19         1              0          1         1       null              null                null
20         3              0          1         15      null              null                null

考虑到如下不同的客户数据,我需要提取与条件匹配的最高优先级规则。下面我给大家举个例子。

让我们考虑以下客户数据数组:

Array
(
    [customer] => 44
    [customer_group] => 1
    [store_id] => 0
    [country] => 15
    [subdivision_one] => 421
    [subdivision_two] => 
)

应考虑的最高优先级规则是 #1。原因如下:

  • 在分配给该规则的所有客户组中,customer_group = 1 是匹配项;
  • 国家/地区匹配;
  • 即使我通过了 customer 和 subdivision_one,这条规则也是匹配的,因为对于这两个属性我根本没有值。如果我的 customer/subdivision_one 有任何值,它不应该匹配。

我有一个部分有效的查询,仅当查询中涉及的所有属性都匹配时才给出结果。

但是,我需要调整此查询,以便在有可用记录(如查询中)或该属性没有可用值时将属性视为匹配。 em> 我希望我已经足够清楚了。

这是查询:

SELECT `r`.*
FROM `rule_attribute_value` `rav`
INNER JOIN `rule` `r`
    ON `rav`.`rule_id` = `r`.`rule_id`
INNER JOIN `rule_attribute` `ra`
    ON `rav`.`attribute_id` = `ra`.`attribute_id`
WHERE
    (`rav`.`store_id` = 0 AND `ra`.`attribute_code` = 'customer' AND `rav`.`value` = 44) OR
    (`rav`.`store_id` = 0 AND `ra`.`attribute_code` = 'customer_group'  AND `rav`.`value` = 1) OR
    (`rav`.`store_id` = 0 AND `ra`.`attribute_code` = 'country' AND `rav`.`value` = 15) OR
    (`rav`.`store_id` = 0 AND `ra`.`attribute_code` = 'subdivision_one' AND `rav`.`value` = 421)
GROUP BY `r`.`rule_id`
HAVING COUNT(DISTINCT `rav`.`attribute_id`) = 4 /* NUMBER OF ATTRIBUTES QUERIED */
ORDER BY `r`.`position` ASC
LIMIT 1;

每次都会发送不同数量的客户属性。有时所有 6 都会有非空值,有时是 5,有时是 4。我只需要找到匹配条件的最高优先级规则。

期待您的回音。

【问题讨论】:

  • 您是否尝试过进行相关调整?
  • AND rav.value = 421 — 这与“该属性没有可用值”如何交互?属性值是 NULL,还是属性(行)完全缺失?
  • 我更新了标题,希望能避免一些负面的反应。但是,问题仍然不清楚(以及标题),并且可能因此而关闭。为了清楚起见,我会花几分钟重新措辞和/或提供最小匹配和不匹配的查询(使用两个属性就足以显示)。
  • 斜体(由我)部分不清楚。我尝试过多种方式阅读它。使用不同的术语来区分搜索值和 (DB) 属性值可能会有所帮助。 “..如果有可用记录(如查询),则认为属性匹配如果该属性没有可用值(这个“属性”是什么意思?)..”
  • “属性”表示“搜索值”,那么另一个OR (store_id = 0 AND attribute_code = 'the_attr' /* no value limit */) 可能是相关的。假设该属性仍然为数据库中的规则“定义”。

标签: mysql sql


【解决方案1】:

我仍在努力为此查询寻找最优化的解决方案,但我认为我找到了更好的方法来解释我的问题。

假设我只想找到与一个属性(客户)匹配的规则。分为三种情况:

  • 如果某个规则的该属性具有我要查找的值,则返回该规则;
  • 如果规则具有此属性,但值与我要查找的值不同,则不返回任何内容;
  • 如果规则根本没有此属性,则返回该规则。

这是我尝试执行的查询,但它没有按预期工作。但是,OR 语法之后的子查询可能有助于更好地理解我要查找的内容。

SELECT `r`.*
FROM `rule_attribute_value` `rav`
INNER JOIN `rule` `r`
    ON `rav`.`rule_id` = `r`.`rule_id`
INNER JOIN `rule_attribute` `ra`
    ON `rav`.`attribute_id` = `ra`.`attribute_id`
WHERE
    (`rav`.`store_id` = 0 AND `ra`.`attribute_code` = 'customer'        AND `rav`.`value` = 2) OR (NOT EXISTS(SELECT * FROM `coriolan_b2bvariables_rule_attribute_value` `ravs` WHERE `ravs`.`rule_id` = `rav`.`rule_id` AND `rav`.`store_id` = 0 AND `ra`.`attribute_code` = 'customer'))
GROUP BY `r`.`rule_id`
HAVING COUNT(DISTINCT `rav`.`attribute_id`) = 1 /* 1 IS THE NUMBER OF ATTRIBUTES BEING QUERIED */
ORDER BY `r`.`position` ASC
LIMIT 1;

这是一个只有一个属性的例子,但我总共有五个属性。但是,我觉得如果我能找到一个属性的解决方案,我可以做剩下的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 2016-08-05
    • 1970-01-01
    • 2014-03-13
    • 2019-07-20
    • 1970-01-01
    • 2020-07-24
    相关资源
    最近更新 更多