无法生成有效的SQL请求。 MySQL的

时间:2016-07-08 15:56:05

标签: mysql sql datetime

我需要提出一个请求,要求所有图书馆卡在本月结束并且没有将图书归还图书馆的人。 我已经提出要求查找本月图书馆卡结束的人:

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中显示为'Give'。如果某人带回了一本书,它会在history.actionHistory中显示为“Take”。 这是我的桌子。请帮忙!

        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
);

1 个答案:

答案 0 :(得分:1)

对于初学者,您可以使用MySQL's LAST_DAY() function,就像这样,

     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

您对读者有一个标准:本月票据到期。书上还有另一个标准:签出多个标准。诀窍是让每个查询分别工作,然后加入它们。