我需要提出一个请求,需要带走所有借书证在本月到期且尚未将书籍归还给图书馆的人。我提出了一个要求,找到借书证在本月结束的人:
select reader.nameReader from reader where year(reader.validityOfTicket)=year(current_date()) and month(reader.validityOfTicket)=month(current_date())
and day(reader.validityOfTicket)>day(current_date())
但我不能把所有没有还书的人都带到图书馆。如果有人拿了一本书,它会以"给"这样的history.actionHistory
显示。如果有人带回了一本书,它会以"Take"这样的history.actionHistory
显示。这是我的表格。请帮忙!
create table author(
idAuthor int auto_increment NOT NULL,
nameAuthor VARCHAR(30) NOT NULL,
surnameAuthor VARCHAR(40),
PRIMARY KEY(idAuthor)
);
create table book(
idBook int NOT NULL,
title varchar(20) NOT NULL,
publishingHouse varchar(60) NOT NULL,
publishingDate DATE NOT NULL,
location VARCHAR(30) NOT NULL,
accessType enum('Full','Restricted') NOT NULL,
currentState enum('Store','Reader'),
idAuthor int NOT NULL ,
PRIMARY KEY(idBook),
foreign Key (`idAuthor`) references `author`(`idAuthor`)
ON DELETE CASCADE ON UPDATE CASCADE
);
create table reader(
idReader int auto_increment NOT NULL,
surnameReader varchar(30) NOT NULL,
nameReader varchar(30) NOT NULL,
patronymicReader varchar(30) NOT NULL,
validityOfTicket DATE NOT NULL,
category enum('Full', 'Restricted') NOT NULL,
PRIMARY KEY(idReader)
);
create table history(
idHistory int auto_increment NOT NULL,
dateHistory DATE NOT NULL,
actionHistory enum('Give','Take'),
idReader int NOT NULL,
idBook int NOT NULL,
PRIMARY KEY(idHistory),
foreign key (`idReader`) REFERENCES `reader`(`idReader`)
ON DELETE CASCADE ON UPDATE CASCADE
);
对于初学者来说,你可以使用 MySQL 的 LAST_DAY()
函数,就像这样,
reader.validityOfTicket >= LAST_DAY(CURRENT_DATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH
AND reader.validityOfTicket < LAST_DAY(CURRENT_DATE()) + INTERVAL 1 DAY
以查找本月到期的门票。如果这样做,您将能够在validityOfTicket
列上使用索引来加快查询速度。
然后,您必须为每个图书馆顾客计算已赠送但未带走的书籍。这样的东西可能会起作用。
SELECT idReader,
SUM( CASE WHEN actionHistory = 'Give' THEN 1
WHEN actionHistory = 'Take' THEN -1
ELSE 0 END ) booksGiven
FROM history
GROUP BY idReader
然后,可以将该摘要查询视为子查询,并将其联接到另一个子查询。
select reader.nameReader
from reader
join (
SELECT idReader,
SUM( CASE WHEN actionHistory = 'Give' THEN 1
WHEN actionHistory = 'Take' THEN -1
ELSE 0 END ) booksGiven
FROM history
GROUP BY idReader
) books on reader.readerId = books.readerId
where reader.validityOfTicket >= LAST_DAY(CURRENT_DATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH
and reader.validityOfTicket < LAST_DAY(CURRENT_DATE()) + INTERVAL 1 DAY
and books.booksGiven > 0
你对读者有一个标准:票在本月到期。你对书籍还有另一个标准:不止一本借出。诀窍是让每个查询单独工作,然后连接它们。