我正在创建一个图书馆管理系统。
我正在尝试通过带有内部联接功能的VB.NET查询SQL数据库,并将数据返回到datagridview,我正在寻找的是返回某种东西,我不知道进行下一步的最佳方法。 / p>
我有一个名为 Onloan 的表,其中包含有关贷款的基本信息,用户 UNID 的ID,书的ISBN,开始日期和结束日期以及返回日期,然后内部与登记表(对于用户)和目录表(对于帐簿)结合在一起,以创建有关什么贷款有效,针对谁和谁的完整图片,但是我在程序上具有重置功能,允许管理员或高级图书馆员重置特定表(例如,用户表),但当前代码不会显示任何结果,因为用户表为空,显然这不会因为我使用的语句而导致,这意味着仪表板不会是正确的
SELECT OnLoan.UNID, OnLoan.ISBN, Catalogue.Title
, Enrolment.Firstname + ' ' + Enrolment.Lastname As 'Full Name'
, Enrolment.House + Enrolment.TutorGroup as Form
, OnLoan.StartDate, OnLoan.EndDate
FROM (Catalogue
INNER JOIN OnLoan ON Onloan.ISBN = Catalogue.ISBN)
INNER JOIN Enrolment ON Enrolment.UNID = OnLoan.UNID
WHERE OnLoan.OnLoan = 1
and OnLoan.EndDate >= CONVERT(datetime, '" & DateTime.Now.ToString("yyyy-MM-dd") & "' )
该图像用于onloan和过期的datagrid中的仪表板,即使数据未完成,我也需要信息。只需在此处放置“未知用户”或其他内容即可。
我只想要我应该查看的领域的信息和参考,如果您能够编辑我的代码并让我使用它,那太好了,但是您可以提供的任何信息和帮助将不胜感激。
答案 0 :(得分:3)
您需要调查外部联接。这些类型的JOINS将从特定方面返回JOIN的所有结果,无论另一个表中是否有匹配项。我在postgres中创建了您的表格,然后运行了它。
表格创建
CREATE TABLE Catalogue (
Title VARCHAR,
ISBN VARCHAR,
PRIMARY KEY (ISBN)
);
CREATE TABLE Enrolment (
UNID serial PRIMARY KEY,
Firstname VARCHAR,
Lastname VARCHAR,
House VARCHAR,
TutorGroup VARCHAR
);
CREATE TABLE OnLoan (
UNID serial PRIMARY KEY,
ISBN VARCHAR,
OnLoan integer,
StartDate TIMESTAMP DEFAULT NOW(),
EndDate TIMESTAMP DEFAULT (NOW() + interval '21 days')
);
用数据播种表
INSERT INTO Catalogue (Title, ISBN) VALUES ('Harry Potter and the Sorcerer''s Stone', '978-0439708180');
INSERT INTO Catalogue (Title, ISBN) VALUES ('Harry Potter and the Chamber of Secrets', '978-0439064873');
INSERT INTO Catalogue (Title, ISBN) VALUES ('Harry Potter And The Prisoner Of Azkaban', '978-0439136365');
INSERT INTO Catalogue (Title, ISBN) VALUES ('Harry Potter And The Goblet Of Fire', '978-0439139601');
INSERT INTO Enrolment (Firstname, Lastname, House, TutorGroup) VALUES ('Harry','Potter','Gryffindor','Granger Study Group');
INSERT INTO Enrolment (Firstname, Lastname, House, TutorGroup) VALUES ('Hermione','Granger','Gryffindor','Granger Study Group');
INSERT INTO Enrolment (Firstname, Lastname, House, TutorGroup) VALUES ('Ronald','Weasley','Gryffindor','Granger Study Group');
INSERT INTO Enrolment (Firstname, Lastname, House, TutorGroup) VALUES ('Draco','Malfoy','Slytherin','Snape''s Dungeon Group');
INSERT INTO OnLoan (UNID, ISBN, OnLoan)
VALUES (
(SELECT e.UNID FROM Enrolment e WHERE e.Lastname='Malfoy'),
(SELECT c.ISBN FROM Catalogue c WHERE c.TITLE='Harry Potter and the Chamber of Secrets'),
1
);
您可以看到Malfoy有一笔贷款
SELECT \
o.UNID, o.ISBN, \
c.Title, \
CONCAT(e.Firstname, ' ', e.Lastname) full_name, \
CONCAT(e.House, ' ', e.TutorGroup) form, \
o.StartDate, o.EndDate \
FROM OnLoan o
INNER JOIN Enrolment e ON o.UNID=e.UNID
INNER JOIN Catalogue c ON o.ISBN=c.ISBN
WHERE o.OnLoan = 1
AND o.EndDate >= NOW()
;
unid | isbn | title | full_name | form | startdate | endda
te
------+----------------+-----------------------------------------+--------------+--------------------------------+----------------------------+---------------
-------------
4 | 978-0439064873 | Harry Potter and the Chamber of Secrets | Draco Malfoy | Slytherin Snape' Dungeon Group | 2020-05-09 22:31:36.086555 | 2020-05-30 22:
31:36.086555
(1 row)
从系统中删除Malfoy
DELETE FROM Enrolment WHERE Lastname='Malfoy';
DELETE 1
再次运行查询,您将看不到Malfoy的任何贷款。他干净利落
SELECT \
o.UNID, o.ISBN, \
c.Title, \
CONCAT(e.Firstname, ' ', e.Lastname) full_name, \
CONCAT(e.House, ' ', e.TutorGroup) form, \
o.StartDate, o.EndDate \
FROM OnLoan o
INNER JOIN Enrolment e ON o.UNID=e.UNID
INNER JOIN Catalogue c ON o.ISBN=c.ISBN
WHERE o.OnLoan = 1
AND o.EndDate >= NOW()
;
unid | isbn | title | full_name | form | startdate | enddate
------+------+-------+-----------+------+-----------+---------
(0 rows)
您需要研究的是外部联接。内部联接意味着要在联接的左侧和右侧都必须存在一条记录。使用OUTER JOIN,您可以看到有一笔贷款,但是用户已经走了。
SELECT \
o.UNID, o.ISBN, \
c.Title, \
CONCAT(e.Firstname, ' ', e.Lastname) full_name, \
CONCAT(e.House, ' ', e.TutorGroup) form, \
o.StartDate, o.EndDate \
FROM OnLoan o
LEFT OUTER JOIN Enrolment e ON o.UNID=e.UNID
INNER JOIN Catalogue c ON o.ISBN=c.ISBN
WHERE o.OnLoan = 1
AND o.EndDate >= NOW()
;
unid | isbn | title | full_name | form | startdate | enddate
------+----------------+-----------------------------------------+-----------+------+----------------------------+----------------------------
4 | 978-0439064873 | Harry Potter and the Chamber of Secrets | | | 2020-05-09 22:31:36.086555 | 2020-05-30 22:31:36.086555
(1 row)
答案 1 :(得分:0)
如果要允许Enrolment
中不匹配的关系,可以在引入该表时使用left join
,并使用coalesce()
来分配默认值:
SELECT
ol.UNID,
ol.ISBN,
ca.Title,
COALESCE(en.Firstname + ' ' + en.Lastname, 'Uknown User') As FullName,
COALESCE(en.House + en.TutorGroup, 'Unknown Form') as Form,
ol.StartDate,
ol.EndDate
FROM Catalogue ca
INNER JOIN OnLoan ol ON ol.ISBN = ca.ISBN
LEFT JOIN Enrolment en ON en.UNID = ol.UNID
WHERE
ol.OnLoan = 1
and ol.EndDate >= cast(getdate() as date)
旁注:
不要对列别名使用单引号-它们用于字符串文字-而是使用方括号(或者更好的是,使用不需要引用的列别名)
join
周围的嵌套括号是多余的(仅MS Access要求这样做)
表别名使查询更易于读写
无需使用参数即可获取当前日期,您可以直接在查询中完成
答案 2 :(得分:0)
我做了更多的研究,这是我想要的完全外部联接,因为我一直认为它是错误的,所以我只是忽略了它。