我得处理公司部门的一个旧数据库。我们使用这个数据库进行硬件管理、分配和跟踪。
我即将在c#中建立一个新的前端,因为当前的MS访问正在缓慢地完成这项任务。
(为了更好地理解,我把表格和行的名称翻译成英文)
tbl_hardware包含HW_ID、序列号、类型、型号、品牌等列(或硬件的必要信息)。
tbl_hardware_assignment包含列ID、HW_ID (与tbl_hardware.ID匹配)、nameID(与tbl_accounts.PersID匹配,以及从创建条目时的int值形成日期YYYYMMDD (不是,我的想法.))。
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语句。)
这里有更多的示例输出 巴斯丁
发布于 2013-07-26 10:15:56
您不需要将子查询重新连接到来自它们的表上,您也可以直接连接到它们上。
与其直接加入一整组表,您还可以考虑如何形成子查询,以获得正确的组成部分。
如下所示可能是你所追求的:
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 这有正确的身份证吗?如果没有,你能找出这两个表之间的关系吗?
发布于 2013-07-26 08:48:55
我会把这个写在评论中,但我没有得到所需的代表点。
你试过改变你的加入吗?考虑到输出,我建议可能尝试内部连接。
发布于 2013-08-01 14:12:03
我想我掌握了基本知识
此选择现在返回正确的值:
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我认为这是我的方法,作为第一批的结果,正确的。
对此有什么改进或想法吗?
我从这里那里得到了最后的帮助
谢谢大家的帮助!
https://stackoverflow.com/questions/17875720
复制相似问题