左边只为SQL中的特定行加入?

时间:2011-06-01 15:29:02

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

我有另一个相当奇怪的问题。我有以下结构:

CREATE TABLE [dbo].[Event]
(
    Id int IDENTITY(1,1) NOT NULL,
    ApplicationId nvarchar(32) NOT NULL,
    Name nvarchar(128) NOT NULL,
    Description nvarchar(256) NULL,
    Date nvarchar(16) NOT NULL,
    Time nvarchar(16) NOT NULL,
    EventType nvarchar(16) NOT NULL,
    SourceId int NOT NULL,
    CONSTRAINT Event_PK PRIMARY KEY CLUSTERED ( Id ) WITH (
        PAD_INDEX = OFF, 
        STATISTICS_NORECOMPUTE = OFF, 
        IGNORE_DUP_KEY = OFF, 
        ALLOW_ROW_LOCKS = ON, 
        ALLOW_PAGE_LOCKS  = ON
    ),
    CONSTRAINT Event_Source FOREIGN KEY (SourceId) REFERENCES [dbo].[Source](Id)
)

CREATE TABLE [dbo].[Source]
(
    Id int IDENITY(1,1) NOT NULL,
    Name nvarchar(128) NOT NULL,
    Description nvarchar(256) NULL,
    CONSTRAINT Source_PK PRIMARY KEY CLUSTERED ( Id ) WITH (
        PAD_INDEX = OFF, 
        STATISTICS_NORECOMPUTE = OFF, 
        IGNORE_DUP_KEY = OFF, 
        ALLOW_ROW_LOCKS = ON, 
        ALLOW_PAGE_LOCKS  = ON
    )
)

事件表中的数据必须以网格显示。在我之前的问题中,我学会了如何正确地查询和显示数据,同时仅显示每个ApplicationId的最后一条记录(也就是...对其进行分组并显示每个组的最后一条记录)。 (http://stackoverflow.com/questions/6201253/how-to-get-the-last-record-per-group-in-sql)谢谢@Anthony Faull,@ Damien_The_Unbeliever以及其他为此答案做出贡献的人

不幸的是,我遇到了一个新的要求,它涉及到该表的SourceId和EventType字段。

基本上,新要求规定,对于EventType('APP_CLOSE'和'APP_START')列中的特定值,请抓取源的名称。其他一切显示'NULL'或其他一些预定义值。

我正在尝试创建一个容纳此请求的视图,并尝试使用LEFT OUTER JOIN。问题是Event表中的某些记录在SourceId中有值,而且我没有JOIN为这些记录带来的数据,除非EventType字段是'APP_CLOSE'或'APP_START'。

关于如何做到这一点的任何想法?

修改 *

由于有人指出我在解释问题所在,我决定采取后续行动:

事件:

| Id | ApplicationId  | Name  | Description | Date       |Time     | EventType | SourceId |
+----+----------------+-------+-------------+------------+---------+-----------+----------+
|1   |2202            |XYZ    | Test        | 05/31/2011 |10:30:55 | APP_CLOSE | 2        |
+----+----------------+-------+-------------+------------+---------+-----------+----------+
|2   |2709            |zyx    | Test        | 05/31/2011 |11:27:55 | APP_START | 4        |
+----+----------------+-------+-------------+------------+---------+-----------+----------+
|3   |2709            |zyx    | Test        | 05/31/2011 |17:09:55 | APP_PAUSE | 1        |

来源表:

| Id | Name              | Description |
+----+-------------------+-------------+
| 2  | Process Watcher   |             |
+----+-------------------+-------------+
| 4  | Interrupt Handler |             |
+----+-------------------+-------------+
| 1  | User Input        |             |
+----+-------------------+-------------+

结果(查询或查看):

| Id | ApplicationId  | Name  | Description | Date       |Time     | EventType | Source Name          |
+----+----------------+-------+-------------+------------+---------+-----------+----------------------+
|1   |2202            |XYZ    | Test        | 05/31/2011 |10:30:55 | APP_CLOSE | Process Watcher      |
+----+----------------+-------+-------------+------------+---------+-----------+----------------------+
|2   |2709            |zyx    | Test        | 05/31/2011 |11:27:55 | APP_START | Interrupt Handler    |
+----+----------------+-------+-------------+------------+---------+-----------+----------------------+
|3   |2709            |zyx    | Test        | 05/31/2011 |17:09:55 | APP_PAUSE |                      |       

这个想法是,即使用户可以暂停应用程序,用户也不是软件的有形内容。因此,在报告已发生的事件时,我只能报告由软件组件引起的事件。换句话说,我现在只需要根据特定事件类型(APP_CLOSE和APP_START)引入源名称。

谢谢,

马丁

3 个答案:

答案 0 :(得分:3)

select e.*, s.Name, ISNULL(s.Name,'Predefined Value')
from [Event] as e
left join [Source] as s on (s.Id = e.SourceId)
                       and (e.EventType in ('APP_CLOSE','APP_START'))

答案 1 :(得分:0)

如果我理解你,你有一个值,如果它是某个值,则显示它,否则显示null:

这很简单,只需使用案例陈述

选择  当col = 5然后'五个活着!'别的'这只是jive!'结束 从表

答案 2 :(得分:0)

select * from [dbo].[Source] right outer join [dbo].[Event]
on [dbo].[Source].Id = [Event].id 
and ([dbo].[Event].EventType  = 'APP_CLOSE' 
OR [dbo].[Event].EventType  = 'APP_START')

这将显示事件的每一列,以及仅当 eventtype ='APP_CLOSE'或'APP_START'

时来源的值

这是你想要的吗?