1

我必须处理公司部门的旧数据库。我们使用这个数据库来管理分配和跟踪的硬件。

我即将在 c# 中建立一个新的前端,因为当前的 MS Access 正在为这项任务减慢速度。

(我将表和行的名称翻译成英文,以便更好地理解)

  • 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 匹配,以及自(创建条目时格式化日期 [YYYYMMDD] 的 int 值)(不是,我的想法...) )

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

这是我当前的 SQL 语句

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
      )

结果:

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

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

知道我的错误在哪里吗?

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

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

结果:

10497   20120601
10498   20120601
11554   20120601
12353   20120601
13665   20120918
13196   20121129
14616   20130701
15073   20130705
9778    20130725

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

以下是更多示例输出 PASTEBIN

4

3 回答 3

2

您不需要将子查询连接回它们来源的表,您可以直接加入它们。

而不是直接加入一大堆表,您可以查看形成获得正确组成部分的子查询

类似以下的内容可能是您所追求的:

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 之间关系的所有列

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 

这会得到正确的ID吗?如果没有,您是否能够找出这两个表之间的关系应该涉及什么?

于 2013-07-26T10:15:56.593 回答
0

我会将此放在评论中,但我没有获得所需的代表点。

你试过改变你的加入吗?查看输出我建议可能尝试 INNER JOIN。

于 2013-07-26T08:48:55.843 回答
0

我想我掌握了基础知识

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

    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

结果

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

我认为这是我将采用的方式,因为前几个结果是正确的。

对此有何改进或想法?

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

谢谢大家的帮助!

于 2013-08-01T14:12:03.373 回答