我需要找出某个功能的有效价格
大海捞针(订单)中的每个特征(此处
F1
)必须与价格规则相匹配。有效价格是特征交集最多的价格。
此图显示了价格规则与不同订单之间的映射。与功能 F1 相关的价格基于价格规则表中的功能与订单中的功能之间的交集。
示例
F1
的价格取决于功能(F1, F2, F3)
F1
的价格可以通过选择F1
的价格规则来确定,该规则在与干草堆的交集中具有最多的元素(顺序)。此示例具有针对功能
F1
的三个价格规则和三个不同的订单。
F1
与 F1
的价格规则相匹配;正确的价格是6F1+F2
) 与 F1
的 Pricerule 相匹配;正确的价格是4F1+F2+F3
) 的 F1
;正确的价格是2此查询是我尝试连接记录,但存在许多重复和错误的连接记录
SELECT op.OrderId, op.Id as OrderPositionId, op.FeatureId,
f.Featurename, pr.Price
FROM OrderPositions op
INNER JOIN FeatureCombinations fc ON op.FeatureId = fc.FeatureId
INNER JOIN Features f on op.FeatureId = f.Id
INNER JOIN PriceRules pr ON fc.PriceRuleId = pr.Id;
从目前的结果来看,所有带有(x)的记录都是错误的
订单ID | 订单位置ID | 功能 ID | 功能名称 | 价格 |
---|---|---|---|---|
401 | 211 | 1 | F1 | 6 |
402 | 221× | 1 | F1 | 6 |
403 | 231× | 1 | F1 | 6 |
401 | 211 | 1 | F1 | 4 |
402 | 221× | 1 | F1 | 4 |
403 | 231× | 1 | F1 | 4 |
402 | 222× | 2 | F2 | 4 |
403 | 232× | 2 | F2 | 4 |
401 | 211× | 1 | F1 | 2 |
402 | 221× | 1 | F1 | 2 |
403 | 231 | 1 | F1 | 2 |
402 | 222× | 2 | F2 | 2 |
403 | 232× | 2 | F2 | 2 |
403 | 233× | 3 | F3 | 2 |
如何确定某个功能的哪个价格规则最匹配 (
elements from order ∩ elements from pricerule
)?
创建表
CREATE TABLE Features(
Id INTEGER PRIMARY KEY,
Featurename TEXT
);
CREATE TABLE PriceRules(
Id INTEGER PRIMARY KEY,
Price REAL
);
CREATE TABLE FeaturesPriceRules(
FeatureId INTEGER,
PriceRuleId INTEGER,
FOREIGN KEY(FeatureId) REFERENCES Features(Id),
FOREIGN KEY(PriceRuleId) REFERENCES PriceRules(Id)
);
CREATE TABLE FeatureCombinations(
PriceRuleId INTEGER,
FeatureId INTEGER,
FOREIGN KEY(PriceRuleId) REFERENCES PriceRules(Id),
FOREIGN KEY(FeatureId) REFERENCES Features(Id)
);
CREATE TABLE OrderPositions(
Id INTEGER PRIMARY KEY,
OrderId INTEGER,
FeatureId INTEGER,
FOREIGN KEY(FeatureId) REFERENCES Features(Id)
);
创建记录
INSERT INTO Features (Id, Featurename)
VALUES (1, 'F1'), (2, 'F2'), (3, 'F3'),
(4, 'F6'), (5, 'F7'), (6, 'F9'),
(7, 'E1'), (8, 'ZA2');
INSERT INTO PriceRules (Id, Price)
VALUES (101, '6.00'), (102, '4.00'), (103, '2.00'),
(105, '24.00'), (106, '22.00');
INSERT INTO FeaturesPriceRules (FeatureId, PriceRuleId)
VALUES (1, 101), (1, 102), (1, 103),(7, 105),(7, 106);
INSERT INTO FeatureCombinations (PriceRuleId, FeatureId)
VALUES (101, 1), (102, 1), (102, 2),
(103, 1), (103, 2),(103, 3),
(105, 7), (106, 7), (106, 8);
INSERT INTO OrderPositions(Id, OrderId, FeatureId)
VALUES (211, 401, 1), (221, 402, 1),(222, 402, 2),
(231, 403, 1),(232, 403, 2),(233, 403, 3);
另请参阅此 带有示例记录的 Sqlfiddle 演示
注意:在此查询中,我实现了 CTE,用于计算订单是否符合规则。
答案:
;WITH cteFeatureCombinationsNeeded AS (
SELECT fc.PriceRuleId, IFNULL(COUNT(fc.FeatureId), 0) countOfFeaturesNeeded
FROM FeatureCombinations fc
GROUP BY fc.PriceRuleId
)
, cteFeatureCombinationsProvided AS (
SELECT op.OrderId, fc.PriceRuleId, fc.FeatureId,
IFNULL(COUNT(fc.FeatureId), 0) countOfFeaturesProvided
FROM OrderPositions op
LEFT JOIN FeatureCombinations fc
ON op.FeatureId = fc.FeatureId
WHERE fc.PriceRuleId IS NOT NULL
GROUP BY op.OrderId, fc.PriceRuleId
)
SELECT op.OrderId, op.Id as OrderPositionId, op.FeatureId,
f.Featurename, MIN(pr.Price)
FROM OrderPositions op
LEFT JOIN FeatureCombinations fc
ON op.FeatureId = fc.FeatureId
LEFT JOIN cteFeatureCombinationsNeeded cfcrn
ON cfcrn.PriceRuleId = fc.PriceRuleId
LEFT JOIN cteFeatureCombinationsProvided cfcrp
ON cfcrp.PriceRuleId = fc.PriceRuleId
AND cfcrp.OrderId = op.OrderId
INNER JOIN Features f
ON f.Id = cfcrp.FeatureId
INNER JOIN PriceRules pr
ON pr.Id = cfcrp.PriceRuleId
WHERE
countOfFeaturesNeeded = countOfFeaturesProvided
GROUP BY op.Id, op.FeatureId
ORDER BY op.OrderId, cfcrp.countOfFeaturesProvided, fc.FeatureId, pr.Price
另请参阅此 带有示例记录的 Sqlfiddle 演示
从当前结果所有记录:
订单ID | 订单位置ID | 功能 ID | 功能名称 | 价格 |
---|---|---|---|---|
401 | 211 | 1 | F1 | 6 |
402 | 221 | 1 | F2 | 4 |
402 | 222 | 2 | F2 | 4 |
403 | 231 | 1 | F3 | 2 |
403 | 232 | 2 | F3 | 2 |
403 | 233 | 3 | F3 | 2 |
用于创建包含记录的表的 SQL 语句
创建表格
CREATE TABLE Features(
Id INTEGER PRIMARY KEY,
Featurename TEXT
);
CREATE TABLE PriceRules(
Id INTEGER PRIMARY KEY,
Price REAL
);
CREATE TABLE FeaturesPriceRules(
FeatureId INTEGER,
PriceRuleId INTEGER,
FOREIGN KEY(FeatureId) REFERENCES Features(Id),
FOREIGN KEY(PriceRuleId) REFERENCES PriceRules(Id)
);
CREATE TABLE FeatureCombinations(
PriceRuleId INTEGER,
FeatureId INTEGER,
FOREIGN KEY(PriceRuleId) REFERENCES PriceRules(Id),
FOREIGN KEY(FeatureId) REFERENCES Features(Id)
);
CREATE TABLE OrderPositions(
Id INTEGER PRIMARY KEY,
OrderId INTEGER,
FeatureId INTEGER,
FOREIGN KEY(FeatureId) REFERENCES Features(Id)
);
创建记录
INSERT INTO Features (Id, Featurename)
VALUES (1, 'F1'), (2, 'F2'), (3, 'F3'),
(4, 'F6'), (5, 'F7'), (6, 'F9'),
(7, 'E1'), (8, 'ZA2');
INSERT INTO PriceRules (Id, Price)
VALUES (101, '6.00'), (102, '4.00'), (103, '2.00'),
(105, '24.00'), (106, '22.00');
INSERT INTO FeaturesPriceRules (FeatureId, PriceRuleId)
VALUES (1, 101), (1, 102), (1, 103),(7, 105),(7, 106);
INSERT INTO FeatureCombinations (PriceRuleId, FeatureId)
VALUES (101, 1), (102, 1), (102, 2),
(103, 1), (103, 2),(103, 3),
(105, 7), (106, 7), (106, 8);
INSERT INTO OrderPositions(Id, OrderId, FeatureId)
VALUES (211, 401, 1), (221, 402, 1),(222, 402, 2),
(231, 403, 1),(232, 403, 2),(233, 403, 3);