这个让我头疼得厉害!基本上,我需要显示一个位置列表,存储在那里的当前项目以及拥有它的人。我创建了4个表,并填充了数据。
设置:MSSQL 2008
我正在寻找的是来自物品和所有者的tbl_locationHistory的“Top(1)”,因为在每个位置任何时候都只能有一个物品或一个物主。请记住,tbl_locationHistory可能有多位数据,我只需要为每一位提取最新的ID(例如,最高的ownerID,历史表中当前可用的最高itemID)。
LOCID LOCNAME
ITEMID ITEMNAME
OWNERID OWNERNAME
locHistID LOCID ITEMID OWNERID dateModified
我尝试将所有这些表与连接一起加入。但是我意识到这不起作用,因为我没有撤回“所有者”或“项目”的顶部ID,因此显示的数据将是不准确的。
我想到的一件事是我应该将历史表分成两部分:1 x所有者到位置和1 x项到位 - 但是我现在处于SQL的极限,所以可以用一些指针来做正确的方向,因为不知道采用哪种方式。
因此,即使我必须打破历史记录表,我也需要帮助。
更新01/11/12
好的,我将在这里粘贴一些代码。
我是一个古老的学校经典ASP编码器.....还没有必要继续前进!我使用经典的asp和MSSQL来创建这个应用程序。我也使用Dreamweaver,因此希望将查询放在那里,这样我就可以使用DW CS6中的“绑定”功能了。
这是我原来的疑问:
SELECT DISTINCT p.pID, p.cliID, p.pNo, p.pName, p.dtCommissioned,
p.description, ps.plotStatus, pt.plotType, o.oSalutation, o.oFname, o.oSname, man.manName,
mod.model, sl.width, sl.length, sl.yr
FROM history AS ph INNER JOIN owners AS o ON ph.ownerID
= o.ownerID INNER JOIN StockList AS sl ON ph.stockID = sl.stkID
INNER JOIN manufacturers AS man ON sl.make = man.manID
INNER JOIN models AS mod ON sl.model = mod.cID FULL OUTER
JOIN plotType AS pt RIGHT OUTER JOIN
plots AS p ON pt.plotTypeID = p.plotType LEFT OUTER JOIN
plotStatus AS ps ON p.pStatus = ps.plotStatusID ON ph.plotID = p.pID
WHERE (p.cliID = value)
ORDER BY p.pNo
现在,当我意识到我没有正确查看历史表中的“stockID”的最高HistoryID以及“ownerID”的最高plotHistoryID时,我开始研究如何执行“子查询”每个ID ......这就是我被困住的地方。
我尝试了以下方面的内容:
Select p.pID, p.cliID, p.pNo, p.pName, p.dtCommissioned,
p.description, ps.plotStatus, pt.plotType, o.oSalutation, o.oFname, o.oSname, man.manName,
mod.model, sl.width, sl.length, sl.yr
(Select top 1 ph.plotHistoryID, ownerID
FROM History AS ph
order by ph.plotHistoryID desc)
THEN JOINING ETC
THEN DO ANOTHER SUBQUERY FOR THE OWNER ETC
但是我无法让它工作,但我现在超出了与Sub Queries和JOINS相关的SQL级别。
输出显示将是:
情节编号|剧情名称|情节类型|情节状态|现任主人|当前股票
每个Plot No / Names / Type / Status都会填充数据,因为我需要显示它们。如果所有者\当前股票是空白的,我有一个IF声明说“没有所有者”或“没有找到股票”。
然后,用户可以点击行末的“查看”链接并查看地图/位置的详细信息,并通过QueryString将pID传递到下一页。
这有帮助吗?我现在变得有点绝望了! LOL
答案 0 :(得分:0)
您可以使用ROW_NUMBER
功能来帮助仅获取每个位置的最新历史记录事件,然后使用此功能重新加入所有者和项目:
WITH LocationHistoryExt AS
( SELECT LocID,
ItemID,
OwnerID,
DateModified,
[RowNumber] = ROW_NUMBER() OVER(PARTITION BY LocID ORDER BY DateModified DESC)
FROM tbl_LocationHistory
)
SELECT l.LocName,
i.ItemID,
o.OwnerName,
lh.DateModified
FROM tbl_Location l
INNER JOIN LocationHistoryExt lh
ON l.LocID = lh.LocID
AND RowNumber = 1 -- ONLY LATEST EVENT
INNER JOIN tbl_Item i
ON lh.ItemID = i.ItemID
INNER JOIN tbl_Owner o
ON o.OwnerID = lh.OwnerID
编辑 - 添加说明
顶部是Common table Expression (CTE),在这种情况下,它只是将子查询移出主查询的一种方式,所以
WITH CTE AS
( SELECT A, B, C
FROM T
)
SELECT *
FROM CTE
与执行
完全相同SELECT A, B, C
FROM T
CTE中的ROW_NUMBER将为每个历史事件分配一个行号,具体取决于其中的ORDER
和PARTITION
子句,因此在tbl_LocationHistory中给出以下示例数据:
locHistID | locID | itemID | ownerID | dateModified
----------+-------+--------+---------+--------------
1 | 1 | 1 | 1 | 20121001
2 | 1 | 4 | 2 | 20121002
3 | 1 | 3 | 1 | 20121003 <-- LATEST FOR LocID 1
4 | 2 | 5 | 2 | 20121002
5 | 2 | 1 | 2 | 20121004
6 | 2 | 2 | 3 | 20121005 <-- LATEST FOR LocID 2
我假设您要做的是检索每个位置ID的最新行,并获取与该行关联的itemID和OwnerID,因此解构ROW_NUMBER
函数:
ROW_NUMBER() OVER(PARTITION BY LocID ORDER BY DateModified DESC);
这将为您的数据中的每一行分配一个行号,每个LocID
(PARITION BY locID
)再次从1开始,它将从具有最新修改日期的记录开始编号为1({ {1}})。将其应用于您将获得的样本数据:
ORDER BY DateModified DESC
这是我在查询中在CTE中重新检索的内容,然后当我加入它时,我添加了locHistID | locID | itemID | ownerID | dateModified | RowNumber
----------+-------+--------+---------+--------------+---------------
1 | 1 | 1 | 1 | 20121001 | 3
2 | 1 | 4 | 2 | 20121002 | 2
3 | 1 | 3 | 1 | 20121003 | 1
4 | 2 | 5 | 2 | 20121002 | 3
5 | 2 | 1 | 2 | 20121004 | 2
6 | 2 | 2 | 3 | 20121005 | 1
,这意味着只返回最新的行
RowNumber = 1
剩余部分只是正常连接,以从上面的2行获取适当的位置,所有者和项目。
我希望现在更有意义。如果不让我知道,我会尝试并解释其他任何一点。
编辑2 - 空字段的会计
我稍微更改了选择的顺序,并将FROM tbl_Location l
INNER JOIN LocationHistoryExt lh
ON l.LocID = lh.LocID
AND RowNumber = 1 -- ONLY LATEST EVENT
locHistID | locID | itemID | ownerID | dateModified | RowNumber
----------+-------+--------+---------+--------------+---------------
3 | 1 | 3 | 1 | 20121003 | 1
6 | 2 | 2 | 3 | 20121005 | 1
更改为INNER JOIN
,但主体仍然相同:
LEFT JOIN