简体   繁体   English

MYSQL通过两个参考表合并并选择行

[英]MYSQL combine and select rows by two reference tables

I am losing my mind over this problem, research has not helped. 我对这个问题迷失了方向,研究没有帮助。 Is this an anti-pattern and hard because of that, or is it just me... 因此,这是一种反模式吗?难吗?还是我...

The IDEA here is that we have a single table for every material we use, we have multiple storage shelf's in which that material is stored on. 这里的IDEA是,对于使用的每种物料,我们只有一个表格,我们有多个物料存放在其中的存储架。 Every stocklocation has individual quantities and minimum limits. 每个库存都有单独的数量和最小限制。

What I want to achieve is a single SQL-query that outputs this: 我要实现的是一个输出以下内容的SQL查询:

+-------+------+---------------------+----------+-----------------+
| SL_Id | M_Id | TimeCreated         | Quantity | MinimumQuantity |
+-------+------+---------------------+----------+-----------------+
|     1 |    2 | 2017-11-02 13:04:18 |       10 |               5 |
|     1 |    3 | NULL                |     NULL |              15 |
|     1 |    4 | 2017-11-02 15:56:56 |        7 |            NULL |
+-------+------+---------------------+----------+-----------------+

This is where I am at the moment.... 这就是我现在的位置。

+-------+------+---------------------+----------+-----------------+
| SL_Id | M_Id | TimeCreated         | Quantity | MinimumQuantity |
+-------+------+---------------------+----------+-----------------+
|     1 |    2 | 2017-11-02 13:04:18 |       10 |            NULL |
|     1 |    3 | NULL                |     NULL |              15 |
|     1 |    4 | 2017-11-02 15:56:56 |        7 |            NULL |
+-------+------+---------------------+----------+-----------------+

Here are the tables: 表格如下:

Material 材料

+----+-----------+
| Id | OrderCode |
+----+-----------+
|  2 | asdf      |
|  3 | 75424     |
|  4 | 45567     |
+----+-----------+

StockLocation 库存位置

+----+-------+
| Id | Label |
+----+-------+
|  1 | asdf  |
+----+-------+

Inventory 库存

+----+------------------+-------------+---------------------+----------+
| Id | StockLocation_Id | Material_Id | TimeCreated         | Quantity |
+----+------------------+-------------+---------------------+----------+
|  1 |                1 |           2 | 2017-11-02 13:04:18 |       10 |
|  2 |                1 |           4 | 2017-11-02 15:23:26 |        9 |
|  3 |                1 |           4 | 2017-11-02 15:56:56 |        7 |
+----+------------------+-------------+---------------------+----------+

StockLocationMaterialLimit 库存位置物料限制

+----+------------------+-------------+-----------------+
| Id | StockLocation_Id | Material_Id | MinimumQuantity |
+----+------------------+-------------+-----------------+
|  1 |                1 |           2 |               5 |
|  2 |                1 |           3 |              15 |
+----+------------------+-------------+-----------------+

This is the monster behind failure, 这是失败背后的怪物,

 SELECT 
    SL_Id,
    M_Id,
    TimeCreated,
    Quantity,
    MinimumQuantity
    FROM (
        SELECT
        SL.Id AS SL_Id,
        M.Id AS M_Id,
        I.TimeCreated AS TimeCreated,
        I.Quantity AS Quantity,
        NULL AS MinimumQuantity
        FROM StockLocation SL, Material M
        JOIN Inventory I on I.Id = (
            SELECT Id FROM Inventory I1 WHERE I1.StockLocation_Id=SL.Id AND I1.Material_Id=M.Id ORDER BY I1.TimeCreated DESC LIMIT 1
        )
    UNION
    SELECT
        SL.Id AS SL_Id,
        M.Id AS M_Id,
        NULL AS TimeCreated,
        NULL AS Quantity,
        SLML.MinimumQuantity AS MinimumQuantity
        FROM StockLocation SL, Material M
        JOIN StockLocationMaterialLimit SLML on SLML.Id = (
            SELECT Id FROM StockLocationMaterialLimit SLML1 WHERE SLML1.StockLocation_Id=SL.Id AND SLML1.Material_Id=M.Id LIMIT 1
        )
) tst GROUP BY SL_Id,M_Id

It turned out to be as easy as adding MAX() on those fields which produced NULL values. 事实证明,就像在产生NULL值的那些字段上添加MAX()一样容易。

SELECT 
    M_Id,
    SL_Id,
    TimeCreated,
    MAX(Quantity) AS Quantity,
    MAX(MinimumQuantity) AS MinimumQuantity
    FROM (
        SELECT
        M.Id AS M_Id,
        SL.Id AS SL_Id,
        I.TimeCreated AS TimeCreated,
        I.Quantity AS Quantity,
        NULL AS MinimumQuantity
        FROM StockLocation SL, Material M
        INNER JOIN Inventory I on I.Id = (
            SELECT Id FROM Inventory I1 WHERE I1.StockLocation_Id=SL.Id AND I1.Material_Id=M.Id ORDER BY I1.TimeCreated DESC LIMIT 1
        )
    UNION
    SELECT
        M.Id AS M_Id,
        SL.Id AS SL_Id,
        NULL AS TimeCreated,
        NULL AS Quantity,
        SLML.MinimumQuantity AS MinimumQuantity
        FROM StockLocation SL, Material M
        INNER JOIN StockLocationMaterialLimit SLML on SLML.Id = (
            SELECT Id FROM StockLocationMaterialLimit SLML1 WHERE SLML1.StockLocation_Id=SL.Id AND SLML1.Material_Id=M.Id LIMIT 1
        )
) tst GROUP BY SL_Id, M_Id;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM