Итак, у меня есть панель администратора, которая связана не по идентификатору, а по имени. Таким образом, 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 таблицы в 1 таблицу, используя только одно значение?
Разработчики= я бы РазработчикиИмя выбран
Отсутствует= отсутствующий_id отсутствующее_имя прогулы
Дата = date_id дата_имя дата
У меня есть страница администратора, и на этой странице люди могут создать день отсутствия, когда они отсутствуют. Вот почему у меня есть таблица «Отсутствие». Им нужно только указать свое имя, скажем, Тома Хиддла, и день их отсутствия. Это будет вставлено в базу данных. Это та же история для таблицы Date.
Теперь у меня есть БОТ. По сути, код и запрос, которые я написал, предназначены для исключения людей, которые отсутствуют в определенные дни, И тех, кто находится в отпуске. Я могу заставить работать таблицу «Отсутствующие», правильно исключая отсутствующих людей из запроса. ОДНАКО, теперь я сталкиваюсь с проблемой, когда мне нужно присоединить DateName и AbsentName к значению DevelopersName. Почему я не использую идентификаторы для этого экземпляра? Это просто, когда записи удаляются, выбор идентификатора искажается, и, поскольку я создаю эту систему для компании, в которой я работаю, в ней не может быть места для ошибки, поэтому я использую одинаковые имена для связи таблиц между собой.
Короче говоря, я не использую идентификаторы по нескольким причинам, вместо этого я использую одинаковые имена между таблицами. DateName и AbsentName предназначены для присоединения к DevelopersName. Если я присоединяюсь к одному из них, я получаю результаты. Если я присоединяюсь к обоим, я не получаю ничего.
// 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!
Итак, к вопросу: мне нужна помощь, чтобы вернуть Бадди Френда и Хэнка Сомера в мои результаты. И еще вопрос, есть ли более чистый способ соединения этих таблиц вместе? Вместо использования WHERE, может быть, внутренние соединения?
Начните вопрос SQL, показав схему для всех соответствующих таблиц. Сделайте SHOW CREATE TABLE YourTableName; для каждой таблицы и вставьте его в вопросы как текст (НЕ ИЗОБРАЖЕНИЕ). Пример данных, содержащихся в этих таблицах, также очень полезен. Если возможно, создайте SQLFiddle с определенной схемой и некоторыми предоставленными тестовыми данными. Также представление вашего ожидаемого результата на основе данных таблицы, которые вы показываете в качестве примера.
date.dateName=developers.name Выглядит немного необычно
Согласен, вряд ли найдется дата с таким же именем, как и у разработчика, а вот с август I может повезти ;-)
@ThorstenKettner сделал мой день ;)
Ну, не уверен, почему мне нужно предоставить больше информации, когда это простой вопрос. Таблица A имеет значения aName, таблица B имеет значения bName, таблица C имеет значения cName. Мне нужно имя таблицы A и имя таблицы B для ссылки на cName.
@ThorstenKettner Нет, я не о том, что я имею в виду xD. dateName = Том Что угодно, Дата = 29.12.22. dateName предназначен для ссылки на имя разработчика, которое также является Tom Whatever
Это странно. Таблица с именем date должна содержать даты. Столбец с именем dateName в этой таблице должен быть именем даты (что бы это ни было; «Первый день Рождества»?). Почему строка даты должна содержать имя человека (кроме, может быть, «Санты» ;-)? Пришло время показать нам структуру таблиц, рассказать, как таблицы связаны между собой и что представляет собой строка в таблице. Вы говорите, что считаете свой запрос неправильным. Что заставляет вас думать так? Мы не знаем вашу базу данных, поэтому расскажите нам о ней и покажите образцы данных, чтобы мы поняли.
@ThorstenKettner Теперь он обновлен, надеюсь, я предоставил здесь достаточно информации.
В отсутствующей таблице должен храниться идентификатор разработчика, а не имя, на тот случай, если у вас есть более одного разработчика по имени Джон Смит! Так же не понятно как таблица дат связана с таблицей отсутствия и вообще назначение таблицы дат мне непонятно.
Я также не понимаю, почему удаления могут испортить идентификаторы. Значения автоинкремента не используют повторно удаленные значения, или вы можете использовать uuid или uuid_short для создания уникальных идентификаторов, если автоинкремент вам не подходит.
@Shadow У разработчиков разные выходные дни, поэтому есть таблица отсутствия, они вставляют 1-5 (с понедельника по пятницу) в базу данных, поэтому, если кто-то отсутствует в пятницу, они помещают это в базу данных, а следующий код исключает их из запроса. Дата предназначена для праздников, Это не связано с отсутствием, Отсутствие - это еженедельное отсутствие, а дата - это выбор дня длительного отсутствия. Скажем 3 недели в июне.
@Shadow Сотрите то, что я только что отредактировал. Это не сработает, скажем, Том Хиддл отсутствует в понедельник и пятницу, это означает, что к его имени привязаны 2 записи. Если я использую идентификаторы, это будет ID = 1 и ID = 2, это испортит соединение с таблицей разработчиков. . Вот почему я использую одинаковые имена. Если имена равны, ловите все их записи.
@Wake Вы создаете поле с именем DeveloperID во всех других таблицах и сохраняете идентификатор разработчика, на которого ссылается связанная запись, в этих столбцах.
У нас все еще есть проблемы с пониманием ваших таблиц. Я сказал вам показать примерные данные :-) Из того, что я понимаю на данный момент: 1. Отсутствующая таблица хранит имя разработчика и номер дня. Запись для Джона Смита / 1 означает, что Джон Смит отсутствует каждый понедельник. 2. В таблице дат хранится имя разработчика и дата, чтобы показать, что разработчик отсутствует в отпуске в этот конкретный день. 3. И что теперь? Вы хотите показать все дни и всех разработчиков с информацией о том, доступны они или нет? А нет, «все дни» из вечного прошлого в вечное будущее? Возможно нет. Но тогда что еще? ...
... Возможно, вы хотите посмотреть на определенный день и показать всех разработчиков, доступных в этот день? Или на конкретный день и разработчик скажет, доступны они или нет? Или что еще? Если бы вы показали примерные данные и ожидаемый результат, мы бы уже дали ответ, но сейчас мы все еще в неведении и не знаем, что вы на самом деле хотите выбрать.
Что касается идентификатора разработчика: насколько я могу судить, остальные правы, вы, кажется, еще не поняли, как идентификаторы используются в базе данных. Но, возможно, мы неправильно понимаем проблему, которую вы решаете.
@ThorstenKettner Надеюсь, я дал достаточно информации сейчас?
@Shadow Отредактировал тему






Вы используете синтаксис объединения, который уже устарел на момент разработки MySQL. Странно видеть, что ты его используешь. Может быть, вы по ошибке взяли книгу 1980-х годов для изучения 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;
Это объединяет три таблицы и возвращает все совпадения. Если вы хотите показать разработчикам, даже если у них нет записи в таблице «отсутствует» или «дата», используйте внешние соединения вместо внутренних:
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;
Но хотя это синтаксически правильно, семантически это не имеет большого смысла, потому что отсутствующие дни и праздники не имеют тесной связи. Вы увидите, что Хэнк находится в отпуске 14 июля 2022 г. и отсутствует по вторникам, а также в отпуске 15 июля 2022 г., отсутствует по вторникам и в отпуске 16 июля 2022 г. и отсутствует по вторникам.
Например, более типичный запрос:
-- 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 с SUN-SAT = 1-7 MySQL, нужно немного посчитать.)
Именно то, что мне было нужно здесь, большое спасибо за просвещение по SQL, мой колледж никогда не был так глубок, когда дело доходило до SQL (не было с моего первого года, 2 года без обучения SQL прямо сейчас). Я буду использовать JOIN заранее :)
Пожалуйста, используйте «современный» синтаксис
JOIN(это стандарт уже 30 с лишним лет). Легче читать, писать и поддерживать