首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL连接4个表

SQL连接4个表
EN

Stack Overflow用户
提问于 2013-07-26 07:45:06
回答 3查看 41.3K关注 0票数 1

我得处理公司部门的一个旧数据库。我们使用这个数据库进行硬件管理、分配和跟踪。

我即将在c#中建立一个新的前端,因为当前的MS访问正在缓慢地完成这项任务。

(为了更好地理解,我把表格和行的名称翻译成英文)

  • tbl_hardware
  • tbl_hardware_assignment
  • tbl_accounts
  • tbl_typebradmodel (暂时不重要,和/或不言自明)

tbl_hardware包含HW_ID、序列号、类型、型号、品牌等列(或硬件的必要信息)。

tbl_hardware_assignment包含列ID、HW_ID (与tbl_hardware.ID匹配)、nameID(与tbl_accounts.PersID匹配,以及从创建条目时的int值形成日期YYYYMMDD (不是,我的想法.))。

tbl_account包含PersID、Login等列(其他内部信息)

这是我当前的SQL语句。

代码语言:javascript
复制
SELECT tbl_hardware.HW_ID,
       tbl_hardware.Aktiv,
       tbl_hardware.typebradmodelID,
       tbl_type.tabel AS Type,
       tbl_brand.tabel AS Brand,
       tbl_model.tabel AS Model,
       tbl_accounts.Login,
       tbl_hardware_assignment.since
FROM tbl_hardware
LEFT OUTER JOIN tbl_typebradmodel ON tbl_hardware.typebradmodelID = tbl_typebradmodel.typebradmodelID
LEFT OUTER JOIN tbl_type ON tbl_typebradmodel.TypID = tbl_type.TypID
LEFT OUTER JOIN tbl_brand ON tbl_typebradmodel.MarkeID = tbl_brand.MarkeID
LEFT OUTER JOIN tbl_model ON tbl_typebradmodel.ModelID = tbl_model.ModelID
LEFT OUTER JOIN tbl_hardware_assignment ON tbl_hardware.HW_ID = tbl_hardware_assignment.HW_ID
LEFT OUTER JOIN tbl_accounts ON tbl_hardware_assignment.namenID = tbl_accounts.PersID
WHERE tbl_hardware.Aktiv = 1 AND 
      tbl_hardware.typebradmodelID in 
      (SELECT tbl_typebradmodel.typebradmodelID
       FROM tbl_typebradmodel
       LEFT OUTER JOIN tbl_type ON tbl_typebradmodel.TypID = tbl_type.TypID
       LEFT OUTER JOIN tbl_brand ON tbl_typebradmodel.MarkeID = tbl_brand.MarkeID
       LEFT OUTER JOIN tbl_model ON tbl_typebradmodel.ModelID = tbl_model.ModelID
       WHERE tbl_typebradmodel.MarkeID = 
             (SELECT tbl_brand.MarkeID 
              FROM tbl_brand 
              WHERE tbl_brand.tabel LIKE 'Samsung')
      ) AND 
      tbl_hardware.HW_ID in 
      (SELECT tbl_hardware_assignment.HW_ID 
       FROM tbl_hardware_assignment, 
            (SELECT MAX(tbl_hardware_assignment.since) AS lastchange,
                    tbl_hardware_assignment.HW_ID
             FROM tbl_hardware_assignment 
             GROUP BY tbl_hardware_assignment.HW_ID) lastentry
       WHERE tbl_hardware_assignment.namenID = 
             (SELECT tbl_accounts.PersID 
              FROM tbl_accounts 
              WHERE tbl_accounts.Login = 'MY_USERNAME') AND 
             tbl_hardware_assignment.HW_ID = lastentry.HW_ID AND
             tbl_hardware_assignment.since = lastentry.lastchange
      )

结果:

代码语言:javascript
复制
9778    1   2868    Monitor 24" TFT Samsung SyncMaster 2494HM   USER1   20100218
9778    1   2868    Monitor 24" TFT Samsung SyncMaster 2494HM   USER2   20100218
10497   1   2868    Monitor 24" TFT Samsung SyncMaster 2494HM   USER3   20100810
10498   1   2868    Monitor 24" TFT Samsung SyncMaster 2494HM   USER3   20100810
10498   1   2868    Monitor 24" TFT Samsung SyncMaster 2494HM   USER4   20100819
10497   1   2868    Monitor 24" TFT Samsung SyncMaster 2494HM   USER4   20100819
10497   1   2868    Monitor 24" TFT Samsung SyncMaster 2494HM   MY_USERNAME 20120601
10498   1   2868    Monitor 24" TFT Samsung SyncMaster 2494HM   MY_USERNAME 20120601
9778    1   2868    Monitor 24" TFT Samsung SyncMaster 2494HM   USER3   20130502
9778    1   2868    Monitor 24" TFT Samsung SyncMaster 2494HM   USER5   20130507
9778    1   2868    Monitor 24" TFT Samsung SyncMaster 2494HM   USER3   20130619
9778    1   2868    Monitor 24" TFT Samsung SyncMaster 2494HM   MY_USERNAME 20130725

但是我得到了太多的结果,一个硬件的错误/多个用户映射。

知道我哪里错了吗?

顺便说一句:这条语句仅返回正确的值。

代码语言:javascript
复制
SELECT tbl_hardware_assignment.HW_ID 
FROM tbl_hardware_assignment, 
     (SELECT MAX(tbl_hardware_assignment.since) AS lastchange, 
             tbl_hardware_assignment.HW_ID
      FROM tbl_hardware_assignment 
      GROUP BY tbl_hardware_assignment.HW_ID) lastentry
WHERE tbl_hardware_assignment.namenID = 
      (SELECT tbl_accounts.PersID 
       FROM tbl_accounts 
       WHERE tbl_accounts.Login = 'MY_USERNAME') AND 
      tbl_hardware_assignment.HW_ID = lastentry.HW_ID AND 
      tbl_hardware_assignment.since = lastentry.lastchange

结果:

代码语言:javascript
复制
10497   20120601
10498   20120601
11554   20120601
12353   20120601
13665   20120918
13196   20121129
14616   20130701
15073   20130705
9778    20130725

(因为我不应该把公司的东西移植到办公室之外,所以我希望我没有搞砸任何结果或SQL语句。)

这里有更多的示例输出 巴斯丁

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-26 10:15:56

您不需要将子查询重新连接到来自它们的表上,您也可以直接连接到它们上。

与其直接加入一整组表,您还可以考虑如何形成子查询,以获得正确的组成部分。

如下所示可能是你所追求的:

代码语言:javascript
复制
SELECT tbl_hardware.HW_ID,
       tbl_hardware.Aktiv,
       tbl_hardware.typebradmodelID,
       typebradmodel.Type,
       typebradmodel.Brand,
       typebradmodel.Model,
       lastentry.Login,
       lastentry.since
FROM (SELECT
        tbl_typebradmodel.typebradmodelID,
        tbl_type.tabel AS Type,
        tbl_brand.tabel AS Brand,
        tbl_model.tabel AS Model
    FROM tbl_typebradmodel
    LEFT OUTER JOIN tbl_type ON tbl_typebradmodel.TypID = tbl_type.TypID
    LEFT OUTER JOIN tbl_brand ON tbl_typebradmodel.MarkeID = tbl_brand.MarkeID
    LEFT OUTER JOIN tbl_model ON tbl_typebradmodel.ModelID = tbl_model.ModelID
    ) typebradmodel
LEFT JOIN tbl_hardware ON tbl_hardware.typebradmodelID = typebradmodel.typebradmodelID
LEFT JOIN      
    (SELECT 
        MAX(tbl_hardware_assignment.since) AS lastchange, 
        tbl_hardware_assignment.HW_ID,
        tbl_accounts.Login
    FROM tbl_hardware_assignment
    LEFT OUTER JOIN tbl_accounts ON tbl_hardware_assignment.namenID = tbl_accounts.PersID
    GROUP BY tbl_hardware_assignment.HW_ID,tbl_accounts.Login ) lastentry ON tbl_hardware.HW_ID = lastentry.HW_ID
WHERE tbl_hardware.Aktiv = 1 AND 
    typebradmodel.Brand LIKE 'Samsung' AND
    lastentry.Login = 'MY_USERNAME'

更新这里的关键部分是使lastchange正确,即使用描述tbl_hardware_assignment和tbl_accounts之间关系的所有列

代码语言:javascript
复制
SELECT 
    MAX(tbl_hardware_assignment.since) AS lastchange, 
    tbl_hardware_assignment.HW_ID,
    tbl_accounts.Login
FROM tbl_hardware_assignment
LEFT OUTER JOIN tbl_accounts ON tbl_hardware_assignment.namenID = tbl_accounts.PersID
AND MAX(tbl_hardware_assignment.since) = tbl_accounts.lastchange
GROUP BY tbl_hardware_assignment.HW_ID,tbl_accounts.Login 

这有正确的身份证吗?如果没有,你能找出这两个表之间的关系吗?

票数 2
EN

Stack Overflow用户

发布于 2013-07-26 08:48:55

我会把这个写在评论中,但我没有得到所需的代表点。

你试过改变你的加入吗?考虑到输出,我建议可能尝试内部连接。

票数 0
EN

Stack Overflow用户

发布于 2013-08-01 14:12:03

我想我掌握了基本知识

此选择现在返回正确的值:

代码语言:javascript
复制
    SELECT  tbl_hardware_assignment.ID, 
        tbl_hardware_assignment.HW_ID, 
        tbl_hardware_assignment.namenID, 
        tbl_hardware_assignment.Since,
        tbl_hardware.Knh
FROM tbl_hardware_assignment
INNER JOIN (
            SELECT tbl_hardware_assignment.HW_ID, MAX(tbl_hardware_assignment.ID) lastchange
            FROM tbl_hardware_assignment
            GROUP BY tbl_hardware_assignment.HW_ID
            )
SubSelect ON tbl_hardware_assignment.HW_ID = SubSelect.HW_ID and tbl_hardware_assignment.ID = SubSelect.lastchange
LEFT OUTER JOIN tbl_hardware ON tbl_hardware_assignment.HW_ID = tbl_hardware.HW_ID
WHERE tbl_hardware_assignment.namenID = (SELECT tbl_accounts.PersID FROM tbl_accounts WHERE tbl_accounts.Login = 'MYUSERNAME')
AND tbl_hardware.Aktiv = 1
ORDER BY tbl_hardware.Knh

结果

代码语言:javascript
复制
ID                  HW_ID         namenID     Since        Knh
------------------- ------------- ----------- ----------- -----------
37481               9778          4993        20130725    11130
32506               10497         4993        20120601    11840
32507               10498         4993        20120601    11841
32511               11554         4993        20120601    12876
34226               13196         4993        20121129    14491
37099               14616         4993        20130701    15896

我认为这是我的方法,作为第一批的结果,正确的。

对此有什么改进或想法吗?

我从这里那里得到了最后的帮助

谢谢大家的帮助!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17875720

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档