需要帮助将 2 个表合二为一

Need help joining 2 tables on one

所以我得到了一个管理仪表板,它不是 link 按 ID 而是按名称编辑的。所以developer.name是核心名称,dateName和absentName是为了加入这个developer.name值。

目前我得到的是这个

db.query("SELECT id, name, absentday, date, slack_id, selected 
            FROM developers, absent, date 
            WHERE date.dateName=developers.name 
            AND absent.absentName=developers.name",

我当然知道这是错误的,有人对我如何仅使用一个值使 2 table 加入 1 table 有建议吗?

开发人员= ID 开发商名称 已选择

缺席= absent_id absent_name 缺席天数

日期= date_id date_name 日期

我有一个管理页面,在这个页面上,人们可以在他们不在场时创建一个缺席日。这就是我 table 缺席的原因。他们只需要输入他们的名字,比如汤姆·希德尔,以及他们缺席的那一天。这将被插入到数据库中,这与日期 table.

的情况相同

现在我有一个 BOT,基本上,我编写的代码和查询是为了排除某些日子缺席的人和休假的人。我能够使 Absent table 工作,正确地从查询中排除缺席的人。但是,我现在遇到了必须将 DateName 和 AbsentName 加入 DevelopersName 值的问题。为什么我不为此实例使用 ID?很简单,当记录被删除时,ID 选择会混乱,而且由于我是为我工作的公司创建这个系统它不能有错误的余地,因此我使用与 link [=46= 相同的名称]彼此之间。

所以简而言之,出于多种原因我不使用 ID,而是在 table 之间使用相同的名称。 DateName 和 AbsentName 旨在与 DevelopersName 一起加入,如果我加入其中一个,我会得到结果,如果我同时加入两个,我会得到 none.

// I have a CRUD Dashboard where I can insert absentdays for Developers.
// So lets say Developer Tom Riddle is not present on monday, I'll put his absentday on 1
// Monday to Friday (1-5)
absent = [
  { id: 1, absentName: 'Tom Riddle', absentday: 1},
  { id: 2, absentName: 'Hank Some', absentday: 2},
  { id: 3, absentName: 'Family Man', absentday: 3}
]

// Date is not the same as Absent, Date is a long term deposit of holidays,
// lets say Hank Some Is going on vacation for 3 days!
date = [
  { id: 1, dateName: 'Tom Riddle', date: '2022-05-13'},
  { id: 2, dateName: 'Hank Some', date: '2022-07-14'},
  { id: 3, dateName: 'Hank Some', date: '2022-07-15'},
  { id: 4, dateName: 'Hank Some', date: '2022-07-16'},
  { id: 5, dateName: 'Family Man', date: '2022-06-15'}
]

// This is the core information of the developers. These are NOT the only columns, there are many more, but for sample data I only noted down the most important one's.
developers = [
  { id: 51, developersName: 'Tom Riddle'},
  { id: 52, developersName: 'Hank Some'},
  { id: 53, developersName: 'Family Man'}
]

// Say I run this query
SELECT id, developersName, absentName, absentday FROM developers, absent WHERE absent.absentName=developers.developersName;

// The output will be this
developers = [
  { id: 51, developersName: 'Tom Riddle', absentName: 'Tom Riddle', absentdays: 1},
  { id: 52, developersName: 'Hank Some',  absentName: 'Hank Some',  absentdays: 2},
  { id: 53, developersName: 'Family Man', absentName: 'Family Man', absentdays: 3}
]

// I now have ABSENT joined with DEVELOPERS.
// With MORE code deeper into the file I can exclude absent people from the query
// Let's say It's monday, It would then look like this. 

developers = [
  { id: 52, developersName: 'Hank Some',  absentdays: 2},
  { id: 53, developersName: 'Family Man', absentdays: 3}
]

// This WORKS, my issue at the moment is combining DATE and ABSENT on Developers
// My WANTED result is this
developers = [
  { id: 51, developersName: 'Tom Riddle', absentdays: 1,  date: '2022-05-13'},
  { id: 52, developersName: 'Hank Some',  absentdays: 2,  date: '2022-07-14'},
  { id: 52, developersName: 'Hank Some',  absentdays: 2,  date: '2022-07-15'},
  { id: 52, developersName: 'Hank Some',  absentdays: 2,  date: '2022-07-16'},
  { id: 53, developersName: 'Family Man', absentdays: 3,  date: '2022-06-15'}
]

// After researching myself, Using this query will give these results above ^^
SELECT id, developersName, absentName, absentday FROM developers, absent WHERE absent.absentName=developers.developersName AND date.dateName=developers.developersName;

// With my problem of joining tables being fixed, I run into a new issue.
// Whenever I execute the query above, it will only display people with a DATE
// Let's look at these sample data here. 

absent = [
  { id: 1, absentName: 'Tom Riddle', absentday: 1},
  { id: 2, absentName: 'Hank Some', absentday: 2},
  { id: 3, absentName: 'Family Man', absentday: 3},
  { id: 4, absentName: 'Buddy Friend', absentday: 4}
]
// Hank Some no longer has records in these table since his holidays have passed
// Buddy Friend has no holidays at all.

date = [
  { id: 1, dateName: 'Tom Riddle', date: '2022-05-13'},
  { id: 2, dateName: 'Family Man', date: '2022-06-15'}
]

// If I execute the query
SELECT id, developersName, absentday FROM developers, absent WHERE absent.absentName=developers.developersName AND date.dateName=developers.developersName;

// MY results are this
developers = [
  { id: 51, developersName: 'Tom Riddle',  absentdays: 1,  date: '2022-05-13'},
  { id: 53, developersName: 'Family Man',  absentdays: 3,  date: '2022-06-15'},
]

// It doesn't display the people who have NO holidays.
// Buddy Friend and Hank Some are MISSING!

所以问题是:我需要帮助让 Buddy Friend 和 Hank Some 回到我的结果中。还有一个问题,是否有更简洁的方法将这些 table 连接在一起?与其使用 WHERE,不如使用内连接?

您使用的连接语法在开发 MySQL 时已经 out-dated。看到你使用它很奇怪。也许你误拿了一本80年代的书来学习SQL?最好放弃这个。 MySQL 仍然支持这种旧语法(因为它仍然被允许),但我们不再使用它,因为它的可读性不如显式连接,更容易出错并且不支持外部连接。

这就是我们在过去三年中一直使用的语法中的查询:

SELECT developers.id, developers.developersName, absent.absentday, date.date
FROM developers
INNER JOIN absent ON absent.absentName = developers.developersName 
INNER JOIN date ON date.dateName = developers.developersName;

这将连接三个 table 和 returns 所有匹配项。如果您想向开发人员显示即使他们在缺席或日期 table 中没有条目,请使用外部联接而不是内部联接:

SELECT developers.id, developers.developersName, absent.absentday, date.date
FROM developers
LEFT OUTER JOIN absent ON absent.absentName = developers.developersName 
LEFT OUTER JOIN date ON date.dateName = developers.developersName;

请注意,使用此数据模型时,名称绝不能更改。这可能适用于登录名,但不适用于自然名,例如当人们结婚时名字会改变。因此,更典型的数据库设计是:

CREATE TABLE developer
(
  developer_id   int           not null auto_increment,
  first_name     varchar(100)  not null,
  last_name      varchar(100)  not null,
  primary key (developer_id)
);

CREATE TABLE developer_absent
(
  developer_id   int           not null,
  day_num        int           not null,
  primary key (developer_id, day_num),
  foreign key (developer_id) referencing developer (developer_id)
);

CREATE TABLE developer_holiday
(
  developer_id   int           not null,
  holiday        date          not null,
  primary key (developer_id, holiday),
  foreign key (developer_id) referencing developer (developer_id)
);

查询将变为:

SELECT d.developer_id, d.name, da.day_num, dh.date
FROM developers d
LEFT OUTER JOIN developer_absent da ON da.developer_id = d.developer_id
LEFT OUTER JOIN developer_holiday dh ON dh.developer_id = d.developer_id;

虽然这在句法上是正确的,但在语义上并没有多大意义,因为缺席天数和假期没有密切关系。你会看到汉克在 2022-07-14 休假,周二缺席,2022-07-15 休假,周二缺席,2022-07-16 休假,周二缺席。

一个更典型的查询例如:

-- Who is available on Friday, May 20, 2022
select *
from developer
where developer_id not in 
(
  select developer_id
  from developer_absent
  where day_num = (dayofweek(date '2022-05-20') + 5) % 7 + 1
)
and developer_id not in 
(
  select developer_id
  from developer_holiday
  where holiday = date '2022-05-20'
);

(将您的 MON-SUN = 1-7 与 MySQL 的 SUN-SAT = 1-7 相匹配需要一些数学运算。)