代码之家  ›  专栏  ›  技术社区  ›  blackandorangecat

MySQL双连接/透视表

  •  0
  • blackandorangecat  · 技术社区  · 7 年前

    这里有一个 SQL Fiddle


    我有一张桌子, 库存 其中有些数据如下所示:

     +--------------+---------+---------------+--------------+------------+------------+
    | pmkInventory | fnkPart | inventoryYear | inventoryNum | inventoryR | inventoryC |
    +--------------+---------+---------------+--------------+------------+------------+
    |            1 |      51 |          2016 |            6 | A          |          4 |
    |            2 |    2075 |          2016 |           40 | C          |          4 |
    |            3 |      50 |          2016 |            3 | A          |          8 |
    |            4 |       3 |          2016 |          600 | F          |          3 |
    |            5 |       3 |          2017 |          650 | F          |          3 |
    |            6 |     100 |          2016 |            2 | B          |          1 |
    |            7 |      50 |          2017 |            5 | A          |          8 |
    |            8 |      51 |          2017 |           16 | A          |          4 |
    +--------------+---------+---------------+--------------+------------+------------+
    

    它每年都有每个零件的计数和位置信息。将有超过2年(不仅仅是2016年和2017年存储),但我一次只需要显示两年。

    我需要一个SQL语句来返回如下内容:

    +---------+---------------+--------------+------------+------------+---------------+--------------+------------+------------+
    | fnkPart | inventoryYear | inventoryNum | inventoryR | inventoryC | inventoryYear | inventoryNum | inventoryR | inventoryC |
    +---------+---------------+--------------+------------+------------+---------------+--------------+------------+------------+
    |      51 | 2016          | 6            | A          | 4          | 2017          | 16           | A          | 4          |
    |    2075 | 2016          | 40           | C          | 4          | NULL          | NULL         | NULL       | NULL       |
    |      50 | 2016          | 3            | A          | 8          | 2017          | 5            | A          | 8          |
    |       3 | 2016          | 600          | F          | 3          | 2017          | 650          | F          | 3          |
    |     100 | 2016          | 2            | B          | 1          | NULL          | NULL         | NULL       | NULL       |
    |      40 | NULL          | NULL         | NULL       | NULL       | NULL          | NULL         | NULL       | NULL       |
    |     504 | NULL          | NULL         | NULL       | NULL       | NULL          | NULL         | NULL       | NULL       |
    +---------+---------------+--------------+------------+------------+---------------+--------------+------------+------------+
    

    从我的阅读中,听起来我需要某种透视表,因为MySQL没有内置透视表,所以我需要使用 CASE 声明。 This question 谈到pivot表,但我不知道如何在不使用pivot表的情况下使用它 count 作用我不需要计算任何东西,因为数据库中已经存储了数据——我只需要显示它。


    我想出了一个非透视表解决方案。它正确地显示年份,但不显示具有空值的行。我有一张零件表,里面有几千个零件。我将把库存表加入其中。我想通过做一个 LEFT JOIN 我会得到所有零件,即使库存表中没有指定年份的数据。

    以下是:

    SELECT p.pmkPart, p.partNumber, 
           i1.fnkPart, i1.inventoryYear, i1.inventoryNum, i1.inventoryR, i1.inventoryC, 
           i2.fnkPart, i2.inventoryYear, i2.inventoryNum, i2.inventoryR, i2.inventoryC
    FROM part AS p
    LEFT JOIN inventory as i1
           ON p.pmkPart = i1.fnkPart
    LEFT JOIN inventory as i2
           ON p.pmkPart = i2.fnkPart
    WHERE i1.inventoryYear = 2016
    AND i2.inventoryYear = 2017
    GROUP BY p.pmkPart
    

    这个问题会给我类似的答案。注意它缺少的部分 2075 100 因为它们没有2017年的价值。它还将其他部件排除在外 part 表-中没有值的 inventory 桌子

    +---------+------------+---------+---------------+--------------+------------+------------+---------+---------------+--------------+------------+------------+
    | pmkPart | partNumber | fnkPart | inventoryYear | inventoryNum | inventoryR | inventoryC | fnkPart | inventoryYear | inventoryNum | inventoryR | inventoryC |
    +---------+------------+---------+---------------+--------------+------------+------------+---------+---------------+--------------+------------+------------+
    |      51 | AB-l34     |      51 |          2016 |            6 | A          |          4 |      51 |          2017 |           16 | A          |          4 |
    |      50 | AB-l36     |      50 |          2016 |            3 | A          |          8 |      50 |          2017 |            5 | A          |          8 |
    |       3 | C-5-BT     |       3 |          2016 |          600 | F          |          3 |       3 |          2017 |          650 | F          |          3 |
    +---------+------------+---------+---------------+--------------+------------+------------+---------+---------------+--------------+------------+------------+
    

    有人对我如何修改现有查询以获得正确结果有什么建议吗?或者如何创建符合我要求的透视表?

    我选择的年份需要能够改变,但我一次只能选择两个,2016年和2017年,或者2016年和2018年,或者2017年和2018年,等等。

    我已经想出了如何使用 php MySQL ,但我要转移到一个新平台,在这个平台上,服务器端脚本不是一个选项,所以需要将所有内容都转移到SQL中

    1 回复  |  直到 7 年前
        1
  •  3
  •   user3158212    7 年前

    尝试将年份条件添加到联接本身:

    SELECT p.pmkPart, p.partNumber, 
           i1.fnkPart, i1.inventoryYear, i1.inventoryNum, i1.inventoryR, i1.inventoryC, 
           i2.fnkPart, i2.inventoryYear, i2.inventoryNum, i2.inventoryR, i2.inventoryC
    FROM part AS p
    LEFT JOIN inventory as i1
           ON p.pmkPart = i1.fnkPart
           AND i1.inventoryYear = 2016
    LEFT JOIN inventory as i2
           ON p.pmkPart = i2.fnkPart
           AND i2.inventoryYear = 2017
    

    此外,此查询中没有聚合,因此不需要按任何内容进行分组。