【问题标题】:Left Outer Join, Multi Tables, To Populate Checkboxes in Classic ASP Application左外连接,多表,在经典 ASP 应用程序中填充复选框
【发布时间】:2014-06-11 10:29:56
【问题描述】:

我一直在使用 sql server 2008 中的几个表,这些数据用于 Classic ASP 应用程序中。 以下查询(请参见下文)已用于填充带有复选框的“更新”页面。第一个表 (KSA) 填充复选框,而第二个表 (KSA_Out) 提供用户选中的复选框。每个目标都有一组这些 KSA 复选框,我遇到的问题是我希望 KSA 左连接仍然填充表单的复选框,即使连接表中没有匹配项。

应用程序背后的想法是这样的: 有一个带有表格的页面:每个目标对应一行,每个结果对应一列。 该表由 Objectives 表和 Outcome 表填充,每个单元格中都有一个“添加/编辑”链接,以及一个带有 Querystring 的 URL,该 URL 将 ObjectiveID 和 OutcomeID 传递到下一页,从而更新了 Objective/Outcome 组合。

在更新页面上,有一个用复选框填充表单的查询。 KSA 表填充列表项,而 OutcomesKSA 表以选中复选框的形式提供任何先前用户输入的数据(OutcomesKSA.KSA_Value 字段,它是布尔值)。 ObjOut 表是连接到 Objectives 和 Outcomes 表的联结表。

在应用程序中,我想只获取某个目标/结果组合的数据,如果用户输入的复选框数据存在(OutcomesKSA.KSA_Value 字段,它是布尔值),但仍然只获取表单列表如果没有在 OutcomesKSA 表中输入数据,则从 KSA 表中获取。

目前,我使用的查询没有填充任何内容(请参见下文)。

感谢您在这方面的任何帮助。

以下是数据的显示方式,从一个表到另一个表,以显示数据是如何分散和相关的(我只包括了 PK 和 FK,以显示它们的关系):

Objectives table
ID
5

Outcomes table
ID
4


ObjOut table
ID|ObjectiveID|OutcomeID
1|5|4

OutcomesKSA table
ID|ObjOutID|KSA_ID 
2|1|1
3|1|2
4|1|3


KSA table
ID
1
2
3

查询:

SELECT 
KSA.ID as KSA_ID, KSA.KSA_Version, KSA.KSA_Sort_Order_Number, 
KSA.KSA_Outcome_Number, KSA.KSA_Category as KSA_KSA_Category, 
KSA.KSA_Category_Sub_Num, KSA.KSA_Category_Sub_Num_Descr, 
KSA.KSA_Category_Sub_Num_Sub_Alpha, KSA.KSA_Category_Sub_Num_Sub_Alpha_Descr, 
KSA.KSA_ID as KSA_KSA_ID, KSA.KSA_Descr_Combined as KSA_KSA_Descr_Combined, 
KSA.LastUpdate, KSA.Date_Created, 

OutcomesKSA.KSA_ID as OutcomesKSA_KSA_ID,OutcomesKSA.KSA_Value as OutcomesKSA_KSA_Value,OutcomesKSA.ObjOutID, 

ObjOut.ObjectiveID, ObjOut.OutcomeID, 

Objectives.ID as Obj_Obj_ID 


FROM 
KSA
LEFT OUTER JOIN 
OutcomesKSA
ON 
KSA.ID=OutcomesKSA.KSA_ID 
INNER JOIN 
ObjOut
ON 
OutcomesKSA.ObjOutID=ObjOut.ID 
INNER JOIN 
Objectives
ON 
ObjOut.ObjectiveID=Objectives.ID 

WHERE 
KSA.KSA_Outcome_Number ='1' 
AND 
KSA.KSA_Category ='k' 
AND 
Objectives.ID ='29' 

ORDER BY KSA.KSA_Sort_Order_Number ASC; 

表格:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Objectives](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [CourseID] [int] NOT NULL,
    [Objective] [varchar](max) NULL,
    [LastUpdate] [datetime] NULL,
    [Date_Created] [datetime] NULL,
 CONSTRAINT [PK_Objectives] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Objectives]  WITH NOCHECK ADD  CONSTRAINT [FK_Objectives_Courses] FOREIGN KEY([CourseID])
REFERENCES [dbo].[Courses] ([CourseID])
ON UPDATE CASCADE
GO

ALTER TABLE [dbo].[Objectives] CHECK CONSTRAINT [FK_Objectives_Courses]
GO

ALTER TABLE [dbo].[Objectives] ADD  CONSTRAINT [DF_Objectives_Date_Created]  DEFAULT (getdate()) FOR [Date_Created]
GO

=============

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Outcomes](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [OutcomeGroup] [varchar](50) NULL,
    [OutcomeType] [varchar](50) NULL,
    [OutcomeNumber] [int] NULL,
    [OutcomeName] [varchar](500) NULL,
    [OutcomeDescription] [varchar](max) NULL,
    [OutcomeVersionYear] [varchar](50) NULL,
    [OutcomeVersionSemester] [varchar](50) NULL,
    [LastUpdate] [datetime] NULL,
    [Date_Created] [datetime] NULL,
 CONSTRAINT [PK_Outcomes] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Outcomes] ADD  CONSTRAINT [DF_Outcomes_Date_Created]  DEFAULT (getdate()) FOR [Date_Created]
GO


==========


SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[ObjOut](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ObjectiveID] [int] NULL,
    [OutcomeID] [int] NULL,
    [LastUpdate] [datetime] NULL,
    [Date_Created] [datetime] NULL,
 CONSTRAINT [PK_ObjOut] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[ObjOut]  WITH CHECK ADD  CONSTRAINT [FK_ObjOut_Objectives] FOREIGN KEY([ObjectiveID])
REFERENCES [dbo].[Objectives] ([ID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[ObjOut] CHECK CONSTRAINT [FK_ObjOut_Objectives]
GO

ALTER TABLE [dbo].[ObjOut]  WITH CHECK ADD  CONSTRAINT [FK_ObjOut_Outcomes] FOREIGN KEY([OutcomeID])
REFERENCES [dbo].[Outcomes] ([ID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[ObjOut] CHECK CONSTRAINT [FK_ObjOut_Outcomes]
GO

ALTER TABLE [dbo].[ObjOut] ADD  CONSTRAINT [DF_ObjOut_Date_Created]  DEFAULT (getdate()) FOR [Date_Created]
GO







===========

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[OutcomesKSA](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ObjOutID] [int] NOT NULL,
    [KSA_ID] [int] NULL,
    [KSA_Value] [bit] NULL,
    [LastUpdate] [datetime] NULL,
    [Date_Created] [datetime] NULL,
 CONSTRAINT [PK_OutcomesKSA] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[OutcomesKSA]  WITH CHECK ADD  CONSTRAINT [FK_OutcomesKSA_ObjOut] FOREIGN KEY([ObjOutID])
REFERENCES [dbo].[ObjOut] ([ID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[OutcomesKSA] CHECK CONSTRAINT [FK_OutcomesKSA_ObjOut]
GO

ALTER TABLE [dbo].[OutcomesKSA] ADD  CONSTRAINT [DF_OutcomesKSA_Date_Created]  DEFAULT (getdate()) FOR [Date_Created]



=========================







SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[KSA](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [KSA_Version] [varchar](50) NULL,
    [KSA_Sort_Order_Number] [int] NULL,
    [KSA_Outcome_Number] [varchar](50) NULL,
    [KSA_Outcome_Number_Sort] [varchar](50) NULL,
    [KSA_Category] [char](1) NULL,
    [KSA_Category_Sub_Num] [varchar](50) NULL,
    [KSA_Category_Sub_Num_Sort] [varchar](50) NULL,
    [KSA_Category_Sub_Num_Descr] [varchar](max) NULL,
    [KSA_Category_Sub_Num_Sub_Alpha] [char](1) NULL,
    [KSA_Category_Sub_Num_Sub_Alpha_Descr] [varchar](1000) NULL,
    [KSA_ID] [char](8) NULL,
    [KSA_ID_Sort] [char](8) NULL,
    [KSA_Descr_Combined] [varchar](max) NULL,
    [LastUpdate] [datetime] NULL,
    [Date_Created] [datetime] NULL,
 CONSTRAINT [PK_KSA] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[KSA] ADD  CONSTRAINT [DF_KSA_Date_Created]  DEFAULT (getdate()) FOR [Date_Created]
GO

【问题讨论】:

  • 这个SQL让我头疼。但无论如何,您从 SELECT 语句中得到什么结果?
  • 我知道你的意思。 SELECT 语句返回 0 行。

标签: sql sql-server join outer-join


【解决方案1】:

后来的INNER JOINs 正在有效地将OUTER JOIN 变回INNER。您可以构造查询,以便将多个表 INNER JOINed 放在一起,然后将该集合应用为 OUTER JOIN

此外,WHERE 子句在所有连接之后应用,并且将过滤整个行,因此 OUTER JOIN 将过滤器放在 WHERE 子句和 ON 中是有区别的条款。

关于编码风格的附注。虽然对于代码的格式有很多个人偏好,但它通常应该以易于阅读和理解为目标。我鼓励您考虑一种不同的格式,既适用于您向其他人展示代码时,也适用于您尝试理解您在 6 个月内编写的内容时。

把它们放在一起,这应该是你想要的更多。

SELECT 
    KSA.ID as KSA_ID
    ,KSA.KSA_Version
    ,KSA.KSA_Sort_Order_Number
    ,KSA.KSA_Outcome_Number
    ,KSA.KSA_Category as KSA_KSA_Category
    ,KSA.KSA_Category_Sub_Num
    ,KSA.KSA_Category_Sub_Num_Descr
    ,KSA.KSA_Category_Sub_Num_Sub_Alpha
    ,KSA.KSA_Category_Sub_Num_Sub_Alpha_Descr
    ,KSA.KSA_ID as KSA_KSA_ID
    ,KSA.KSA_Descr_Combined as KSA_KSA_Descr_Combined
    ,KSA.LastUpdate
    ,KSA.Date_Created
    ,OutcomesKSA.KSA_ID as OutcomesKSA_KSA_ID
    ,OutcomesKSA.KSA_Value as OutcomesKSA_KSA_Value
    ,OutcomesKSA.ObjOutID
    ,ObjOut.ObjectiveID
    ,ObjOut.OutcomeID
    ,Objectives.ID as Obj_Obj_ID 
FROM 
    KSA
    LEFT OUTER JOIN (
        OutcomesKSA
        INNER JOIN ObjOut
            ON OutcomesKSA.ObjOutID = ObjOut.ID 
        INNER JOIN Objectives
            ON ObjOut.ObjectiveID = Objectives.ID 
    ) ON KSA.ID = OutcomesKSA.KSA_ID 
        AND Objectives.ID = 29 --filter
WHERE 
    KSA.KSA_Outcome_Number = '1' 
    AND KSA.KSA_Category = 'k' 
ORDER BY KSA.KSA_Sort_Order_Number; 

【讨论】:

  • 这很有帮助。感谢您在这方面的彻底回答和帮助。
  • 是否也可以获得同级表的 LEFT OUTER JOIN ?在与 KSA 表相同的级别、相同的关系上添加了一个新表。 KSA 表和名为 KSA_Priority 的新表在 KSA_Out 联结表中都有外键。是否可以在同一个查询中同时从 KSA 和 KSA_Priority 表中获取所有结果?谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-17
  • 1970-01-01
  • 1970-01-01
  • 2015-09-03
  • 1970-01-01
相关资源
最近更新 更多