我有两天时间试图做这个查询而没有运气。 我有两张桌子' DEMAND'和' DEMAND_STATE' (一对多关系)表DEMAND_STATE有数百万条目。
CREATE TABLE DEMAND
(
ID INT NOT NULL,
DESTINY_ID INT NOT NULL
)
CREATE TABLE DEMAND_STATE
(
ID INT NOT NULL,
PRIORITY INT NOT NULL,
QUANTITY DOUBLE NOT NULL,
CASE_ID INT NOT NULL,
DEMAND_ID INT NOT NULL,
PHASE_ID INT NOT NULL
)
根据CASE_ID和PHASE_ID给出DEMAND_STATE的QUANTITY。我们有N' N'在' M'案例。在所有案例中始终使用相同数量的阶段。我们总是有一个名为' BASE CASE'的初始基本数量。在CASE_ID = 1的情况下。
例如,获取Case(id = 2)和Case Base(id = 1)
的数量select D.*, S.PRIORITY, S.QUANTITY, S.CASE_ID, S.DEMAND_ID, S.PHASE_ID
FROM DEMAND D
join DEMAND_STATE S on (D.ID = S.DEMAND_ID)
WHERE (S.CASE_ID = 2 OR S.CASE_ID = 1)
(仅适用于id = 8)
ID PRIORITY QUANTITY CASE_ID DEMAND_ID PHASE_ID
8 0 85 1 8 1
8 0 83 1 8 2
8 0 88 1 8 3
8 0 89 1 8 4
8 10 85 2 8 1
8 10 84 2 8 2
8 10 86 2 8 3
8 10 89 2 8 4
我们需要在“需求”中获取所有需求。只有具有MAX优先级的每个阶段的数量。这个想法是每个新案例创建都没有重复的DEMAND_STATE数据。只有在Demand-Case-Phase与Case Base不同时才创建新的状态行。这是一个新项目,我们接受模型的更改以获得更好的性能。
我也尝试过MAX计算。对DEMAND_STATE的查询工作正常,但只获取具体DEMAND_ID的数据。此外,我认为这个解决方案可能非常昂贵。
SELECT P.ID, P.QUANTITY, P.CASE_ID, P.DEMAND_ID, P.PHASE_ID
FROM DEMAND_STATE P
JOIN (
SELECT PHASE_ID, MAX(PRIORITY) max_priority, S.DEMAND_ID
from DEMAND_STATE S
WHERE S.DEMAND_ID = 1
AND (S.CASE_ID=1 OR S.CASE_ID=2)
GROUP BY S.PHASE_ID
) SUB
ON (SUB.PHASE_ID = P.PHASE_ID AND SUB.max_priority = P.PRIORITY)
WHERE P.DEMAND_ID = 1
GROUP BY P.PHASE_ID
结果:
ID QUANTITY CASE_ID DEMAND_ID PHASE_ID
1 86 1 1 1
2 85 1 1 2
3 81 1 1 3
8 500 2 1 4
这是预期的结果:
ID ID PRIORITY QUANTITY CASE_ID PHASE_ID
8 1 0 86 1 1 (data from Case Base id=1 priority 0)
8 2 10 85 1 2 (data from Case Baseid=1 priority 0)
8 3 10 81 1 3 (data from Case Base id=1 priority 0)
8 64 10 500 2 4 (data from Case id=2 priority 10)
感谢您的帮助:)
编辑:
Simon提案的结果:
ID QUANTITY CASE_ID DEMAND_ID PHASE_ID
1 86 1 1 1
2 85 1 1 2
3 81 1 1 3
4 84 1 1 4 (this row shouldnt exist)
8 500 2 1 4 (this is the correct row)
还必须加入DEMAND
@didierc回复:
ID ID MAX(S.PRIORITY) QUANTITY CASE_ID PHASE_ID
1 8 10 500 2 4
2 13 10 81 2 1
2 14 10 83 2 2
2 15 10 84 2 3
3 21 10 81 2 1
4 31 10 86 2 3
4 32 10 80 2 4
4 29 10 85 2 1
4 30 10 81 2 2
我们需要每个DEMAND四行,数量为Value。在Case Base中我们有四个数量,在Case 2中我们只改变第4阶段的数量。我们每个需求总共需要四行。
数据库DEMAND_STATE数据:
ID PRIORITY QUANTITY CASE_ID DEMAND_ID PHASE_ID
1 0 86 1 1 1
2 0 85 1 1 2
3 0 81 1 1 3
4 0 84 1 1 4
8 10 500 2 1 4
答案 0 :(得分:0)
如果我正确理解您的问题,子查询的使用应该能够按照您的意愿进行。以下内容:
SELECT
P.ID,
P.QUANTITY,
P.CASE_ID,
P.DEMAND_ID,
P.PHASE_ID
FROM DEMAND_STATE P
INNER JOIN (
-- Next level up groups it down and so gets the rows first returned for each PHASE_ID, which is the highest priority due to the subquery
SELECT
D.PHASE_ID,
D.PRIORITY,
D.DEMAND_ID
FROM (
-- Top level query to get all rows and order them in desc priority order
SELECT
S.PHASE_ID,
S.PRIORITY,
S.DEMAND_ID
FROM DEMAND_STATE S
WHERE S.DEMAND_ID IN (1) -- Update this to be whichever DEMAND_IDs you are interested in
AND S.CASE_ID IN (1,2)
ORDER BY
S.PHASE_ID ASC,
S.DEMAND_ID ASC,
S.PRIORITY DESC
) D
GROUP BY
D.PHASE_ID,
S.DEMAND_ID
) SUB
ON SUB.PHASE_ID = P.PHASE_ID
AND SUB.DEMAND_ID = P.DEMAND_ID
存在顶级子查询以获取您感兴趣的行,并按顺序对它们进行排序,这些顺序允许在PHASE_ID和DEMAND_ID对其进行分组时产生可预测的结果。这反过来允许一个简单的INNER JOIN到DEMAND_STATE希望(除非我误解了你的查询)
这可能仍然很昂贵,但取决于该顶级查询中的数据量。
答案 1 :(得分:0)
我们需要在“需求”中获取所有需求。只有MAX优先级的每个阶段的数量
根据您的示例结果集,我将上述内容翻译为:
SELECT
D.ID, S.ID, MAX(S.PRIORITY), S.QUANTITY, S.CASE_ID, S.PHASE_ID
FROM DEMAND D
LEFT JOIN DEMAND_STATE S
ON D.ID = S.DEMAND_ID
GROUP BY S.PHASE_ID, S.DEMAND_ID
要获得每对的最大优先级(demand_id,phase_id),我们使用以下查询:
SELECT
DEMAND_ID, PHASE_ID, MAX(PRIORITY) AS PRIORITY
FROM DEMAND_STATE
GROUP BY DEMAND_ID, PHASE_ID
接下来,要检索给定需求的一组阶段,只需创建一个内部联接按需状态:
SELECT S.* FROM DEMAND_STATE S
INNER JOIN (
SELECT
DEMAND_ID, PHASE_ID, MAX(PRIORITY) AS PRIORITY
FROM DEMAND_STATE
GROUP BY DEMAND_ID, PHASE_ID
) S2
USING (DEMAND_ID,PHASE_ID, PRIORITY)
WHERE DEMAND_ID = 1
如果要限制可能的情况,请在查询S2
中包含where子句:
SELECT S.* FROM DEMAND_STATE S
INNER JOIN (
SELECT
DEMAND_ID, PHASE_ID, MAX(PRIORITY) AS PRIORITY
FROM DEMAND_STATE
WHERE CASE_ID IN (1,2)
GROUP BY DEMAND_ID, PHASE_ID
) S2
USING (DEMAND_ID,PHASE_ID, PRIORITY)
WHERE DEMAND_ID = 1
但是,您的评论和更新表明MAX(PRIORITY)
似乎并不是非常相关。我的理解是你有一个基本案例,可以在给定场景中被另一个案例覆盖(该场景是对基础案例+其他一些案例)。如果这不正确,请澄清问题正文中的这一点。如果是这种情况,您可以通过PRIORITY
替换CASE_ID
来更改上述查询:
SELECT S.* FROM DEMAND_STATE S
INNER JOIN (
SELECT
DEMAND_ID, PHASE_ID, MAX(CASE_ID) AS CASE_ID
FROM DEMAND_STATE
WHERE CASE_ID IN (1,2)
GROUP BY DEMAND_ID, PHASE_ID
) S2
USING (DEMAND_ID,PHASE_ID, CASE_ID)
WHERE DEMAND_ID = 1
我从优先权中看到的唯一原因是,如果您希望合并超过2个案例,并使用优先权来选择哪个案例将取决于阶段。
您当然可以在DEMAND
上添加内部联接以包含相关的需求数据。