【问题标题】:SQL Server 2008 Join, Union, Multiple Selects?SQL Server 2008 加入、联合、多选?
【发布时间】:2016-10-19 07:45:18
【问题描述】:

在 SQL Server 2008 中创建这个视图真的很吃力。多个连接我没有问题,但我不太确定这次获取所需数据的最佳方法。

我有一个表,“版本”,其中包含包含 JobNumber、版本号、DateCreated、CreatedBy、Status 和描述的列。

我希望在结果中返回所有这些列。

然后它变得更棘手。

我有另一个名为“设备”的表。在该表中,我有 3 列我想与“版本”表交叉引用。这些列是 ModifiedVersion、ModifiedDate 和 ModifiedBy。我需要做的是找到修改行的最后日期,并在与上表中的版本号相同的行中返回该日期。

所以最终的结果是:

<table border="1">
  <tr>
    <td>Job Number</td>
    <td>Version</td>
    <td>Date Created</td>
    <td>Created By</td>
    <td>Last Modified</td>
    <td>Last Modified By</td>
  </tr>
  <tr>
    <td>123</td>
    <td>1.00</td>
    <td>01-01-2016</td>
    <td>User 12</td>
    <td>31-01-2016</td>
    <td>User 16</td>
  </tr>
    <tr>
    <td>123</td>
    <td>2.00</td>
    <td>21-03-2016</td>
    <td>User 8</td>
    <td>15-06-2016</td>
    <td>User 11</td>
  </tr>
<tr>
    <td>456</td>
    <td>1.00</td>
    <td>01-01-2016</td>
    <td>User 12</td>
    <td>31-01-2016</td>
    <td>User 16</td>
  </tr>
    <tr>
    <td>456</td>
    <td>2.00</td>
    <td>21-03-2016</td>
    <td>User 8</td>
    <td>15-06-2016</td>
    <td>User 11</td>
  </tr>
   <tr>
    <td>456</td>
    <td>3.00</td>
    <td>01-04-2016</td>
    <td>User 8</td>
    <td>NULL</td>
    <td>NULL</td>
  </tr>
  </table>

所以问题是我如何选择最后修改日期(使用我知道的“MAX”很容易),但要与版本表中的版本号交叉引用。

版本和设备表都有一个“JobNumber”列,需要在它们之间进行连接。

最后,我将对 CreatedBy 和 ModifiedBy 列进行连接,以给出用户表中保存的用户的实际名称。

我已经尝试过使用派生表和各种连接,我可以非常接近,但是当不同的用户进行修改并且没有进行任何修改时会出现问题。如果没有进行任何修改,我希望 NULL 值出现在结果中。似乎出错的是 ModifiedBy 列的分组。

我能得到的最接近的是这样的:

SELECT     
    dbo.t_ProjectEquipmentVersions.ID, 
    dbo.t_ProjectEquipmentVersions.JobNumber, 
    dbo.t_ProjectEquipmentVersions.VersionNumber, 
    dbo.t_ProjectEquipmentVersions.DateCreated, 
    dbo.t_ProjectEquipmentVersions.CreatedBy,     
    dbo.t_ProjectEquipment.ModifiedVersion, 
    MAX(dbo.t_ProjectEquipment.ModifiedDate) AS LastModifiedDate, 
    dbo.t_ProjectEquipment.ModifiedBy
FROM         
    dbo.t_ProjectEquipmentVersions 
LEFT OUTER JOIN
    dbo.t_ProjectEquipment ON dbo.t_ProjectEquipmentVersions.VersionNumber = dbo.t_ProjectEquipment.ModifiedVersion
GROUP BY 
    dbo.t_ProjectEquipmentVersions.ID, 
    dbo.t_ProjectEquipmentVersions.JobNumber, 
    dbo.t_ProjectEquipmentVersions.VersionNumber, 
    dbo.t_ProjectEquipmentVersions.DateCreated, 
    dbo.t_ProjectEquipmentVersions.CreatedBy, 
    dbo.t_ProjectEquipment.ModifiedVersion, 
    dbo.t_ProjectEquipment.ModifiedBy

这很接近,但我得到了 3 个结果行,而不是我想要的 2 个。这似乎是因为 modifiedBy 列具有不同的用户 ID。如果我从选择中完全删除“ModifiedBy”,我会得到我想要的结果。

对此的任何建议、提示和帮助将不胜感激。

【问题讨论】:

  • 如果ModifiedBy不止一个,你想看哪一个?
  • 我只想要与最近修改日期相对应的那个。
  • 然后使用 Serg 回答 OUTER APPLY 只需根据您的需要更改顺序即可。 order by date

标签: sql sql-server sql-server-2008 join


【解决方案1】:

使用外部应用

SELECT     
    pev.ID, 
    pev.JobNumber, 
    pev.VersionNumber, 
    pev.DateCreated, 
    pev.CreatedBy,     
    pe.LastModifiedDate,
    pe.ModifiedBy
FROM         
    dbo.t_ProjectEquipmentVersions  pev
OUTER APPLY (
    SELECT TOP(1) pe.ModifiedDate AS LastModifiedDate
        ,pe.ModifiedBy 
    FROM dbo.t_ProjectEquipment pe
    WHERE pe.ModifiedVersion = pev.VersionNumber 
    ORDER BY ModifiedBy DESC
) pe 

【讨论】:

  • 唯一的事情是我必须将日期顺序更改为 ASC 以获得最新的更改,猜测这是因为 TOP 1。我现在需要做的唯一一件事是加入我的用户表CreatedBy 和 ModifiedBy 列返回用户名。这些连接会去哪里?
  • 在查询末尾添加 2 个 LEFT JOIN
【解决方案2】:
SELECT     
    dbo.t_ProjectEquipmentVersions.ID, 
    dbo.t_ProjectEquipmentVersions.JobNumber, 
    dbo.t_ProjectEquipmentVersions.VersionNumber, 
    dbo.t_ProjectEquipmentVersions.DateCreated, 
    dbo.t_ProjectEquipmentVersions.CreatedBy,     
    dbo.t_ProjectEquipment.ModifiedVersion, 
    dbo.t_ProjectEquipment.ModifiedDate,
    dbo.t_ProjectEquipment.ModifiedBy
FROM   dbo.t_ProjectEquipmentVersions 
LEFT OUTER JOIN (
                SELECT  E1.ModifiedVersion, E2.ModifiedDate, E1.ModifiedBy
                FROM     t_ProjectEquipment E1
                INNER JOIN 
                    (SELECT ModifiedVersion, MAX(ModifiedDate) AS ModifiedDate
                    FROM    dbo.t_ProjectEquipment 
                    GROUP BY ModifiedVersion, ModifiedBy
                    ) E2
                ON E1.ModifiedVersion = E2.ModifiedVersion
                )   t_ProjectEquipment

    ON dbo.t_ProjectEquipmentVersions.VersionNumber = t_ProjectEquipment.ModifiedVersion

在需要的地方使用 JobId。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-02
    • 2014-07-17
    • 1970-01-01
    • 2012-03-28
    • 1970-01-01
    • 2011-03-11
    相关资源
    最近更新 更多