更正SQL“JOIN”以从主列表创建子集 - 一个表中的id字段到另一个表中的id和标题#VB / C#

问题描述 投票:0回答:2

数据库新手,我可以读取vb.net或c#代码。我想将文件夹中的文件名与这些文件名的主列表及其描述相匹配,并创建一个子集以显示在datagridview控件中。 “Filename”是两个表中的主键:

Table "MasterList" <-- 50,000 records
  Filename 
  Title
 Table "FoundFiles" <-- 2,000 records
  Filename 

经过几周的阅读,我想出了以下内容,两个SQL查询“似乎”都给出了相同的结果。我是否正确地做了一个查询“比另一个更好”?我也对查询中表的顺序感到困惑。哪个是“左”,哪个是“正确”,如果我在“加入”中将它们更正

Dim con As New SqlCeConnection("Data Source=|DataDirectory|\data.sdf")
Dim daMasterList As SqlCeDataAdapter
Dim daSubset As SqlCeDataAdapter
Dim ds As DataSet 

Sub table_load(database As String)
  ds = New DataSet
  daMasterList = New SqlCeDataAdapter(("SELECT * FROM MasterList"), con)
  daMasterList.Fill(ds, "MasterList")
  daSubset = New SqlCeDataAdapter(("SELECT FoundFiles.Filename, MasterList.Title"                                         & _" FROM FoundFiles" & _
                                    " INNER JOIN MasterList" & _
                                    " ON FoundFiles.Filename = Masterlist.Filename"), con)
  daSubset.Fill(ds, "FoundFiles")
  ' load the table into a DataGridView control
  dgvFileList.DataSource = ds.Tables("FoundFiles") 'existing files with titles from the master list
End Sub

这也给了我正在寻找的东西:

daSubset = New SqlCeDataAdapter(("SELECT * FROM MasterList" & _ 
                                 " INNER JOIN FoundFiles" 
                                 " ON MasterList.Filename = FoundFiles.Filename"), con)

想要的结果:

  FoundFiles              MasterList              reduced master or new table
filename1.zip      filename1.zip, accounting       filename1.zip, accounting 
filename2.zip -->  filename2.zip, birth certs  --> filename2.zip, birth certs
filename5.zip      filename3.zip, spreadsheets     filename5.zip, websites
filename8.zip      filename4.zip, real estate      filename8.zip, archived
....               filename5.zip, websites
                   filename6.zip, games
                   filename7.zip, presentations
                   filename8.zip, archived
c# sql vb.net datatable
2个回答
2
投票

如果我正确理解你的问题,它几乎归结为“这两个SQL查询之间有什么区别?”

SELECT FoundFiles.Filename, MasterList.Title
FROM FoundFiles
INNER JOIN MasterList
ON FoundFiles.Filename = Masterlist.Filename

SELECT * 
FROM MasterList 
INNER JOIN FoundFiles
ON MasterList.Filename = FoundFiles.Filename

第一个区别是,在第一个查询中,您明确说明了要返回的列:FoundFiles.Filename, MasterList.Title,但在第二个中使用*,这意味着“给我所有列”。如果这些是唯一存在的列,则会得到相同的结果。

第二个区别是表的顺序,一个有FROM A JOIN B,另一个有FROM B JOIN A。您正在进行的连接类型是内连接,这意味着它只返回在两个表中找到的结果。在这种情况下,连接的顺序并不重要。至于哪个是“左”和“右”的问题,它遵循模式FROM left JOIN right。同样,由于您只获得两者中都存在的结果,因此订单不会更改结果。

至于哪个是“正确的”,它们在语法上都是正确的。您明确列出所需列的第一个版本可能是稍微好一点的选项。它清楚地说明了您希望得到的结果,这有助于优化和代码可读性。您可能希望搜索有关SQL查询的最佳实践的信息。 Here是关于在查询中使用*的Stack Overflow讨论。


1
投票

您使用异常编写的2个SQL语句之间没有区别,第一个SQL将列限制为所需列(推荐),而第二个SQL包括来自两个表的所有列(即使公共fileName列来自两个表,因此复制)。第一个更好。

根据LEFT和RIGHT,只需检查哪一个在左侧或右侧:

     LEFT                  RIGHT
FROM MasterList INNER JOIN FoundFiles

但是在你的查询中,你不想要左或右,你想要INNER JOIN就像你一样。这意味着“给我在两个表中找到的行 - 基于匹配的键,在你的情况下是FileName”。

如果你想要拥有MasterList中的所有文件,无论它们是否也在findFiles中,那么你将使用LEFT [OUTER] JOIN:

FROM MasterList LEFT JOIN FoundFiles

如果在右边使用了masterfiles,那么它将是一个RIGHT JOIN(很少使用)。

© www.soinside.com 2019 - 2024. All rights reserved.