【问题标题】:How to show records from one table that do not exist in another table如何显示一个表中不存在于另一个表中的记录
【发布时间】:2022-01-19 20:14:32
【问题描述】:

这比通常如何显示一个表中不在另一个表中的记录要复杂一些。

相反,一个表中的每条记录应该在另一个表中出现“x”次。

表定义及数据如下:

CREATE TABLE `time_code` (
  `ID` bigint NOT NULL AUTO_INCREMENT,
  `AREA_ID` bigint NOT NULL,
  `TIME_CODE` varchar(10) NOT NULL,
  `DESCRIPTION` varchar(255) NOT NULL,
  `FISCAL_YEAR` bigint NOT NULL,
  PRIMARY KEY (`ID`)
  )

Id, Area, Timecode, Description, Fiscal Year
1, 51, 101, "Project A", 2022
2, 51, 102, "Project B", 2022
CREATE TABLE `schedule_data` (
  `ID` bigint NOT NULL AUTO_INCREMENT,
  `AREA_ID` bigint NOT NULL,
  `TERRITORY_ID` bigint NOT NULL,
  `GROUP_ID` bigint NOT NULL,
  `TIMECODE_ID` bigint NOT NULL,
  `CALENDAR_MONTH` bigint NOT NULL,
  `FISCAL_YEAR` bigint not null,
  PRIMARY KEY (`ID`)
  )
Id, Area, Territory, Group, Timecode ID, Month, Fiscal Year
1, 51, 52, 53, 1, 2, 2022
2, 51, 52, 54, 1, 2, 2022
3, 51, 52, 55, 1, 2, 2022
4, 51, 52, 53, 2, 2, 2022

在本例中,时间码 101 出现在每个组(53、54 和 55)中。时间码 102 仅出现在第 53 组中。它在第 54 组和第 55 组中缺失。

每个时间码必须出现在每个组的 schedule_data 表中(3 次,但可能会因组数而异)

如何编写一个查询来告诉我哪些组缺少时间码?

时间代码适用于整个区域,并且每个组的代码必须只存在一次......即使跟踪的值为零。

编辑以添加组织代码表和示例记录:

// adjacency list model
CREATE TABLE `organization_map` (
  `ID` bigint NOT NULL AUTO_INCREMENT,
  `ORG_CODE` bigint NOT NULL,
  `NAME` varchar(255) NOT NULL,
  `PARENT_ID` bigint NOT NULL,
  `FISCAL_YEAR` bigint NOT NULL,
  PRIMARY KEY (`ID`)
)
Id, Org Code, Name, Parent Id, Fiscal Year
51, 1, "Area 1", 0, 2022
52, 1, "Territory 1", 51, 2022
53, 5, "Group 1", 52, 2022
54, 6, "Group 2", 52, 2022
55, 7, "Group 3", 52, 2022
56, 2, "Territory 2", 51, 2022
57, 14, "Group 4", 56, 2022
58, 15, "Group 5", 56, 2022

【问题讨论】:

  • 你有一个包含所有组的表吗?这会有所帮助。

标签: mysql sql


【解决方案1】:

更新,找到解决方案

创建了计划数据视图以包含组织信息以便于查询。然后写了一个查询来表示时间码到组级别。接下来,使用 not in 子查询查找视图中不存在的时间码。

select
    a.id as area_id, t.id as territory_id, g.id as group_id, tc.time_code
from 
    time_code tc
left join
    organization_map a on a.id = 51
left join
    organization_map t on t.id = 52
left join
    organization_map g on g.id in
    (
        58, 59, 60, 61, 62, 63, 64
    )
where
    tc.FISCAL_YEAR = 2022 and
    tc.TIME_CODE not in
    (
        select
            v.time_code
        from
            schedule_data_view v
        where
            v.calendar_month = 10 and
            v.FISCAL_YEAR = 2021 and
            v.AREA_ID = a.id and
            v.TERRITORY_ID and
            v.group_id = g.id
    )
group by
    a.id, t.id, g.id, tc.TIME_CODE;

【讨论】:

    【解决方案2】:

    基本上,您可以交叉加入组和代码以获得所有可能的组合。然后您可以使用NOT EXISTS 和相关子查询来查找不在计划中的组合。

    SELECT om.id organization_map,
           tc.id time_code
           FROM organization_map AS om
                CROSS JOIN time_code AS tc
           WHERE NOT EXISTS (SELECT *
                                    FROM schedule_data AS sd
                                    WHERE sd.group_id = om.id
                                          AND sd.timecode_id = tc.id);
    

    我不确定fiscal_yearcalendar_month 等其他列。我认为它们只是多余的,甚至不应该存在,但我不知道是什么正是你在这里建模。所以他们可能有自己的位置并成为钥匙的一部分。在后一种情况下,您可能还需要使用这些键列来扩展查询。

    【讨论】:

      猜你喜欢
      • 2012-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      • 2015-08-27
      • 1970-01-01
      相关资源
      最近更新 更多