2016-07-08 10 views
2

今月末にライブラリカードが終了し、図書館に返却されていないすべての人を連れて行く必要があります。有効なSQL要求を作成できません。 MySQL

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

でもない、私は図書館に本を返却h​​as'tすべての人々を取ることができない: 私は図書館カードの端今月中に見つけ人々がいることを要求してきました。 誰かが本を取った場合は、「Give」のようにhistory.actionHistoryに表示されます。誰かが本を持ち帰った場合、「Take」のようにhistory.actionHistoryに表示されます。 私のテーブルはここにあります。ヘルプpls!手始めに

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

クエリの結果、期待する結果、およびサンプル行を表示すると助けが簡単になります。 – rlanvin

答えて

1

、あなたが今月期限切れのチケットを見つけるために、このように、

 reader.validityOfTicket >= LAST_DAY(CURRENT_DATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH 
AND reader.validityOfTicket < LAST_DAY(CURRENT_DATE()) + INTERVAL 1 DAY 

MySQL's LAST_DAY() functionを使用することができます。これを行うと、validityOfTicket列のインデックスを使用してクエリを高速化できます。

あなたは、それぞれの図書館の利用者のために、与えられたもののTakenではない本を数えなければなりません。このような何かが働くかもしれません。

  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 

あなたは今月、チケットの有効期限が切れています。あなたは本のもう一つの基準を持っています:複数のチェックアウト。トリックは、これらのクエリのそれぞれを別々に処理してから、それらを結合することです。

+0

あまりにも多くの!私はSQLで新しく、それにCASE構造体について知らなかった!私はそれについて読むでしょう!もう一つ余裕! –

関連する問題