Php 在SQL中计算级联价格规则
我正在构建一个工具,允许人们将项目发布到类别中。在发布项目之前,需要进行价格计算,以确定向发布项目的用户收取的价格 我提出了使用一个名为Php 在SQL中计算级联价格规则,php,mysql,sql,postgresql,doctrine,Php,Mysql,Sql,Postgresql,Doctrine,我正在构建一个工具,允许人们将项目发布到类别中。在发布项目之前,需要进行价格计算,以确定向发布项目的用户收取的价格 我提出了使用一个名为price\u rule的表来定义规则的概念,它看起来像这样: +------------ + | Field | --------------+ | id | | user | | category | | price | +-------------+ +-----------+--------
price\u rule
的表来定义规则的概念,它看起来像这样:
+------------ +
| Field |
--------------+
| id |
| user |
| category |
| price |
+-------------+
+-----------+---------+-------------+-------+
| id | user | category | price |
+-----------+---------+-------------+-------+
| 1 | NULL | NULL | 10.00 |
+-----------+---------+-------------+-------+
+-----------+---------+-------------+-------+
| id | user | category | price |
+-----------+---------+-------------+-------+
| 1 | NULL | NULL | 10.00 |
+-----------+---------+-------------+-------+
| 2 | Bob | NULL | 8.00 |
+-----------+---------+-------------+-------+
作为一般规则,此数据库将始终具有备用行。此行用于在没有其他规则与特定上下文匹配的情况下确定价格。该行希望这样:
+------------ +
| Field |
--------------+
| id |
| user |
| category |
| price |
+-------------+
+-----------+---------+-------------+-------+
| id | user | category | price |
+-----------+---------+-------------+-------+
| 1 | NULL | NULL | 10.00 |
+-----------+---------+-------------+-------+
+-----------+---------+-------------+-------+
| id | user | category | price |
+-----------+---------+-------------+-------+
| 1 | NULL | NULL | 10.00 |
+-----------+---------+-------------+-------+
| 2 | Bob | NULL | 8.00 |
+-----------+---------+-------------+-------+
有了这一行而没有其他行,一篇文章将始终花费10.00美元
现在假设添加了一行。该表现在如下所示:
+------------ +
| Field |
--------------+
| id |
| user |
| category |
| price |
+-------------+
+-----------+---------+-------------+-------+
| id | user | category | price |
+-----------+---------+-------------+-------+
| 1 | NULL | NULL | 10.00 |
+-----------+---------+-------------+-------+
+-----------+---------+-------------+-------+
| id | user | category | price |
+-----------+---------+-------------+-------+
| 1 | NULL | NULL | 10.00 |
+-----------+---------+-------------+-------+
| 2 | Bob | NULL | 8.00 |
+-----------+---------+-------------+-------+
加入这条规则后,Bob将在所有类别中为每篇帖子支付8.00美元,其余用户将在所有类别中支付10.00美元
如果我们添加更多包含特定用户和特定类别的行:
+-----------+---------+-------------+-------+
| id | user | category | price |
+-----------+---------+-------------+-------+
| 1 | NULL | NULL | 10.00 |
+-----------+---------+-------------+-------+
| 2 | Bob | NULL | 8.00 |
+-----------+---------+-------------+-------+
| 3 | Bob | Bicycles | 9.50 |
+-----------+---------+-------------+-------+
| 4 | Meghan | Bicycles | 5.00 |
+-----------+---------+-------------+-------+
当鲍勃去做一个自行车类的职位时,他的价格是9.5美元。任何其他类别,Bob将支付8.00美元
梅根现在将支付5.00美元在自行车类张贴,10.00美元的每一个其他类别
任何类别(包括自行车)的所有其他用户都将支付10.00美元的默认价格
在现实世界中,此表可能有数百行,这将允许对发布的价格进行精细控制
如果你想知道,这个概念背后有商业动机,因为在这个系统中发布帖子的成本并不总是确定的。相反,它是基于与发布帖子的用户的业务关系
当试图设计一个查询,返回应用于所发帖子的单个最相关的定价规则时,问题就会暴露出来。查询此表时,我可以访问以下信息:用户和类别。我尝试了多种查询组合,并阅读了一些SQL概念,如IFNULL
和COALESCE
,但我还没有找到正确的查询
另一个问题是,在我们的实际应用程序中,price\u rule
表中有一个额外的列用于计算价格,但为了简化本问题中使用的示例,我省略了这个细节。我觉得同样的解决方案可能适用于计算中使用的2列或3列
请注意,应用程序代码中存在强制约束,以防止添加重复的规则
我们还使用了条令ORM和条令DBAL,所以如果您的查询通过查询生成器或DQL开箱即用,您的答案将被认为更有价值。标准SQL中的解决方案也可以在PostgreSQL或MySQL中使用
尽管我希望尽可能避免这种情况,但有效的解决方案可能还包括从
price\u rule
表中获取每一行,并使用应用程序代码确定适用的规则。如果您的解决方案基于此概念,请包含相关的伪代码。一个简单的方法是按适合度对每一行进行评分,然后选择得分最高的一行,以匹配Bob/Bicycles等
SELECT price,
CASE WHEN "user" = 'Bob' THEN 2
WHEN "user" IS NULL THEN 0
ELSE -10 END +
CASE WHEN "category" = 'Bicycles' THEN 1
WHEN "category" IS NULL THEN 0
ELSE -10 END score
FROM field
ORDER BY score DESC LIMIT 1;
名称匹配得2分,类别匹配得1分。任何不匹配都会得到-10,如果没有其他匹配,默认值将获胜
如果有大量行,则需要添加一个WHERE子句,该子句只查找匹配的行(即匹配名称/类别或null),只需在筛选的行上使用order by即可。
我将上述查询转换为一个函数,只是为了便于测试。但是如果你愿意的话,就把它打开
在MySQL中,我不记得如何使函数成为原始函数:
我们不是来为你工作的。冗长详细的编写是不相关的,因为它归结为“为我编写这个查询”。这不是这个网站的工作方式。您可以显示您的查询,解释为什么它不起作用,我们将尝试修复它。这肯定是一个有趣的问题。你已经试过什么了?你调查过工会了吗
与RECURSIVE
(RECURSIVE CTE)尝试一系列选项并选择第一个合适的选项?先生,你说得对。这正是我自己刚刚想出的答案,它完全符合需要。