具有额外优先级列的 Mysql JOIN

标签 mysql sql database

我有两天时间尝试执行此查询,但没有成功。 我有两个表“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
)

DEMAND_STATE 的 QUANTITY 是根据 CASE_ID 和 PHASE_ID 给出的。我们在“M”个案例中有“N”个阶段。所有案例中的阶段数始终相同。在 CASE_ID = 1 的案例中,我们始终有一个名为“BASE CASE”的初始基础数量。

例如获取 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

我们需要为“DEMAND”中的所有需求获取具有 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,我们需要四行具有数量值的行。在案例库中,我们有四个数量,在案例 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

最佳答案

We need to obtain for all Demand in 'DEMAND' only the Quantity for Each Phase with MAX priority

我根据你的示例结果集翻译了上面的内容,如下:

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)n 的最大优先级,我们使用以下查询:

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 上添加一个内部联接,以包含相关的需求数据。

关于具有额外优先级列的 Mysql JOIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24550885/

相关文章:

php - 用户输入多个表单字段通过php从mysql表中检索相关记录

mySQL NATURAL JOIN 显示类似于 LEFT OUTER JOIN 的结果

php - mysqli::real_connect(): (HY000/2002): 实时连接被拒绝

Android 数据库连接和游标哦,我的

mysql - 如何使用 jdbctemplate 保存或更新数据库中的多个值

mysql - 具有嵌套内连接和相同列名的 SQL 查询

PHP:检查MySQL时间值是否大于5分钟

sql - 如何删除另一个表中存在的行?

android - 如何使用 ADB 从 android 设备中提取 sqlite 数据库?

mongodb - 数据库和项目订单(一般)