簡體   English   中英

當一個表為空時,查詢在內部連接期間不返回任何內容

[英]Query returns nothing during inner join when one table empty

我正在創建一個圖書館管理系統。

我正在嘗試使用內部連接 function 通過 VB.NET 查詢 SQL 數據庫,並將數據返回到 datagridview,我正在尋找的最好的方法是不知道的返回。

我有一個名為Onloan的表,其中包含有關貸款的基本信息、用戶UNID的 id、書籍的 ISBN、開始和結束日期以及返回日期,然后與用戶和目錄的注冊表內部連接表,對於書籍,創建一個完整的貸款是活躍的,對於什么和誰,但是我在程序上有一個重置 function,它允許管理員或高級圖書管理員重置一個特定的表,例如用戶表,但是當前代碼不會顯示任何結果是用戶表是空的,顯然不是因為我使用的語句,這意味着儀表板將不正確

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 和過期數據網格中的儀表板,即使數據未完成,我也想要信息。 只需在那里放置一個“未知用戶”或其他東西。

儀表板的圖像

我只想要我應該查看的區域的信息和參考,如果您能夠編輯我的代碼並讓我使用它,那就太好了,但是您可以提供的任何信息和幫助將不勝感激。

您需要調查 OUTER JOIN。 這些類型的 JOIN 將返回來自特定端的 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
    );

執行查詢並查看添加外部聯接如何提供幫助

你可以看到馬爾福有一筆貸款

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)

從系統中刪除馬爾福

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 可以看到有一個 Loan,但用戶已經離開。

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)

如果要允許在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周圍的嵌套括號在 SQL 服務器中是多余的(只有 MS Access 需要)

  • 表別名使查詢更易於讀寫

  • 不需要使用參數來獲取當前日期,您可以直接在查詢中進行

我做了更多的研究,它是我想要的完全外部連接,我只是一直忽略它,因為我一直看錯了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM