【问题标题】:SQL Server - Subselect returns more than 1 row. How to properly select all?SQL Server - 子选择返回超过 1 行。如何正确选择全部?
【发布时间】:2019-02-27 15:30:12
【问题描述】:

与这个问题相关的是表格“tAttributes”

CREATE TABLE [dbo].[tAttributes](
    [GUID] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
    [Attribute] [varchar](50) NOT NULL,
    [RelatedGUID] [uniqueidentifier] NULL,
    [LevelLow] [decimal](12, 2) NULL,
    [LevelHigh] [decimal](12, 2) NULL,
    [LevelStep] [decimal](12, 2) NULL,
    [AttributeLevel] [decimal](12, 2) NULL,
    [Description] [varchar](100) NULL,
    [AutoselectGUID] [uniqueidentifier] NULL,
    [CompanySystem] [bit] NOT NULL,
    [PeopleSystem] [bit] NOT NULL,
    [SearchSystem] [bit] NOT NULL,
    [Populate] [bit] NOT NULL,
    [Synonyms] [varchar](255) NULL,
    [TimeEntered] [datetime] NULL,
    [UserEnteredGUID] [uniqueidentifier] NULL,
    [TimeUpdated] [datetime] NULL,
    [UserUpdatedGUID] [uniqueidentifier] NULL,
    [UpdateHistory] [varchar](255) NULL,
    [Stamp] [timestamp] NULL,
 CONSTRAINT [PK_tAttributes] PRIMARY KEY CLUSTERED 
(
    [GUID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY],
 CONSTRAINT [IX_AttributeRelatedGUID] UNIQUE NONCLUSTERED 
(
    [Attribute] ASC,
    [RelatedGUID] 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]

它有属性例如:

GUID|Attribute|RelatedGUID|....
1   | Val1    | 2         |
3   | Val2    | NULL      |
4   | val3    | 5         |  

Val1 是一个属性,Val2 其中 RelatedGUID 为 NULL 是一个类别

活生生的例子,即:

F0F9EA32-C3AC-48A9-B6BE-09807B720818| gaming | 09E898CC-5DE2-4664-B9B2-14F17FBC37DB
32B74398-83C9-4225-81E2-0A1CB6C67954 | Function skills | NULL

“游戏”是一个属性

“功能技能”是一个类别

我如何对其进行子选择,以便在“属性”列中,我将只有属性、RelatedGUID 与 NULL 不同的值,而在“类别”、类别、具有相关GUID 等于 NULL 的值列中?

我有这个问题:

select tsearch.Description,

tcompany.CompanyName,
tcompany.GUID as CompanyGuid,
tcompanylocation.LocationName,
tsearchtype.SearchType,
tsearchresult.searchresult,
tpeople.GUID as PersonPlacedGuid,
tpeople.LastName As PersonPlacedLName,
tpeople.Firstname As PersonPlacedFName,
tsearch.SearchNotes,
( select tpeople.Firstname  from tpeople where tpeople.guid=tSearch.RepresentativeGUID) as repfirstname, 
( select tpeople.Lastname from tpeople where tpeople.guid=tSearch.RepresentativeGUID) as replastname,
tsearch.RepresentativeGUID as RepGuid,
tposition.Position as backgroundposition,
tdepartment.Department as backgrounddepartment,
( select tpeople.Lastname from tpeople where tpeople.guid=tSearch.ReferredByGUID) as referredbylastname,
( select tpeople.FirstName from tpeople where tpeople.guid=tSearch.ReferredByGUID) as referredbylastname,
tsearch.ReferredByGUID as PersonwhorefferedGuid,
( select tcompany.CompanyName from tCompany where tCompany.guid=tSearch.PlacedFromGUID) as placedfrom,
tinstantstatustype.InstantStatus,
tWorkbench.WorkbenchName,
( select tpeople.Lastname from tpeople where tpeople.guid=tInstantStatus.PeopleGUID) as Candlastname,
( select tpeople.FirstName from tpeople where tpeople.guid=tInstantStatus.PeopleGUID) as candFirstname,
tInstantStatus.ForClientNotes,
tinstantstatus.InstantStatusNotes as InstanttatusNotesSummary,
( select top 1 tAttributes.Attribute from tAttributes where tAttributes.RelatedGUID is not NUll ) as Attributes,
( select top 1 tAttributes.Attribute from tAttributes where tAttributes.RelatedGUID is  NUll ) as Categories


from tSearch


full join tCompany on tsearch.CompanyGUID = tcompany.guid
full join tcompanylocation on tcompanylocation.guid= tcompany.LocationGUID
full join tSearchType on tsearchtype.GUID = tSearch.SearchTypeGUID
full join tSearchResult on tSearchResult.GUID = tsearch.SearchResultGUID
full join tPeople on tPeople.GUID = tsearch.PlacedGUID
full join tPosition on tPosition.GUID = tsearch.PositionGUID
full join tDepartment on tdepartment.GUID = tsearch.DepartmentGUID
full join tInstantStatus on tInstantStatus.SearchGUID = tSearch.guid
full join tInstantStatusType on tInstantStatusType.GUID = tInstantStatus.InstantStatusGUID 
full join tWorkbench on tWorkbench.SearchGUID=tsearch.GUID
full join tSearchCluendex on tSearchCluendex.CPSGUID=tsearch.GUID
full join tAttributes on tAttributes.GUID=tSearchCluendex.AttributeGUID

这里我使用了“top 1”技巧,但问题是类别多于 1,因此“top 1”不是完整的解决方案:

( select top 1 tAttributes.Attribute from tAttributes where tAttributes.RelatedGUID is not NUll ) as Attributes,
( select top 1 tAttributes.Attribute from tAttributes where tAttributes.RelatedGUID is  NUll ) as Categories

提前致谢!

更新 1

基于@Shungo 提示。

这也不起作用:

select tsearch.Description,

tcompany.CompanyName,
tcompany.GUID as CompanyGuid,
tcompanylocation.LocationName,
tsearchtype.SearchType,
tsearchresult.searchresult,
tpeople.GUID as PersonPlacedGuid,
tpeople.LastName As PersonPlacedLName,
tpeople.Firstname As PersonPlacedFName,
tsearch.SearchNotes,
( select tpeople.Firstname  from tpeople where tpeople.guid=tSearch.RepresentativeGUID) as repfirstname, 
( select tpeople.Lastname from tpeople where tpeople.guid=tSearch.RepresentativeGUID) as replastname,
tsearch.RepresentativeGUID as RepGuid,
tposition.Position as backgroundposition,
tdepartment.Department as backgrounddepartment,
( select tpeople.Lastname from tpeople where tpeople.guid=tSearch.ReferredByGUID) as referredbylastname,
( select tpeople.FirstName from tpeople where tpeople.guid=tSearch.ReferredByGUID) as referredbylastname,
tsearch.ReferredByGUID as PersonwhorefferedGuid,
( select tcompany.CompanyName from tCompany where tCompany.guid=tSearch.PlacedFromGUID) as placedfrom,
tinstantstatustype.InstantStatus,
tWorkbench.WorkbenchName,
( select tpeople.Lastname from tpeople where tpeople.guid=tInstantStatus.PeopleGUID) as Candlastname,
( select tpeople.FirstName from tpeople where tpeople.guid=tInstantStatus.PeopleGUID) as candFirstname,
tInstantStatus.ForClientNotes,
tinstantstatus.InstantStatusNotes as InstanttatusNotesSummary,
( select a1.Attribute from tAttributes where tAttributes.RelatedGUID is not NUll ) as Attributes,
( select a1.Attribute from tAttributes where tAttributes.RelatedGUID is  NUll ) as Categories


from tSearch


full join tCompany on tsearch.CompanyGUID = tcompany.guid
full join tcompanylocation on tcompanylocation.guid= tcompany.LocationGUID
full join tSearchType on tsearchtype.GUID = tSearch.SearchTypeGUID
full join tSearchResult on tSearchResult.GUID = tsearch.SearchResultGUID
full join tPeople on tPeople.GUID = tsearch.PlacedGUID
full join tPosition on tPosition.GUID = tsearch.PositionGUID
full join tDepartment on tdepartment.GUID = tsearch.DepartmentGUID
full join tInstantStatus on tInstantStatus.SearchGUID = tSearch.guid
full join tInstantStatusType on tInstantStatusType.GUID = tInstantStatus.InstantStatusGUID 
full join tWorkbench on tWorkbench.SearchGUID=tsearch.GUID
full join tSearchCluendex on tSearchCluendex.CPSGUID=tsearch.GUID
full join tAttributes on tAttributes.GUID=tSearchCluendex.AttributeGUID
LEFT JOIN tAttributes AS a1 ON a1.GUID=tSearchCluendex.AttributeGUID

返回:

Msg 512, Level 16, State 1, Line 3
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

更新 2:

看起来更好,不幸的是属性和类别具有相同的值。我希望属性具有相关GUID 不为NULL 的值和相关GUID 的值为NULL 的类别。

如何指定这个条件?

select tsearch.Description,

tcompany.CompanyName,
tcompany.GUID as CompanyGuid,
tcompanylocation.LocationName,
tsearchtype.SearchType,
tsearchresult.searchresult,
tpeople.GUID as PersonPlacedGuid,
tpeople.LastName As PersonPlacedLName,
tpeople.Firstname As PersonPlacedFName,
tsearch.SearchNotes,
( select tpeople.Firstname  from tpeople where tpeople.guid=tSearch.RepresentativeGUID) as repfirstname, 
( select tpeople.Lastname from tpeople where tpeople.guid=tSearch.RepresentativeGUID) as replastname,
tsearch.RepresentativeGUID as RepGuid,
tposition.Position as backgroundposition,
tdepartment.Department as backgrounddepartment,
( select tpeople.Lastname from tpeople where tpeople.guid=tSearch.ReferredByGUID) as referredbylastname,
( select tpeople.FirstName from tpeople where tpeople.guid=tSearch.ReferredByGUID) as referredbylastname,
tsearch.ReferredByGUID as PersonwhorefferedGuid,
( select tcompany.CompanyName from tCompany where tCompany.guid=tSearch.PlacedFromGUID) as placedfrom,
tinstantstatustype.InstantStatus,
tWorkbench.WorkbenchName,
( select tpeople.Lastname from tpeople where tpeople.guid=tInstantStatus.PeopleGUID) as Candlastname,
( select tpeople.FirstName from tpeople where tpeople.guid=tInstantStatus.PeopleGUID) as candFirstname,
tInstantStatus.ForClientNotes,
tinstantstatus.InstantStatusNotes as InstanttatusNotesSummary,
tAttributes.Attribute as Attributes,
a1.Attribute as Categories


from tSearch


full join tCompany on tsearch.CompanyGUID = tcompany.guid
full join tcompanylocation on tcompanylocation.guid= tcompany.LocationGUID
full join tSearchType on tsearchtype.GUID = tSearch.SearchTypeGUID
full join tSearchResult on tSearchResult.GUID = tsearch.SearchResultGUID
full join tPeople on tPeople.GUID = tsearch.PlacedGUID
full join tPosition on tPosition.GUID = tsearch.PositionGUID
full join tDepartment on tdepartment.GUID = tsearch.DepartmentGUID
full join tInstantStatus on tInstantStatus.SearchGUID = tSearch.guid
full join tInstantStatusType on tInstantStatusType.GUID = tInstantStatus.InstantStatusGUID 
full join tWorkbench on tWorkbench.SearchGUID=tsearch.GUID
full join tSearchCluendex on tSearchCluendex.CPSGUID=tsearch.GUID
full join tAttributes on tAttributes.GUID=tSearchCluendex.AttributeGUID
LEFT JOIN tAttributes AS a1 ON a1.GUID=tSearchCluendex.AttributeGUID

更新 3:

select * from tAttributes where RelatedGUID is null;

列出 11 个类别,RelatedGUID 为 NULL 的条目。

现在当我按照@iamdave 解决方案的建议尝试时:

select tsearch.Description,

tcompany.CompanyName,
tcompany.GUID as CompanyGuid,
tcompanylocation.LocationName,
tsearchtype.SearchType,
tsearchresult.searchresult,
tpeople.GUID as PersonPlacedGuid,
tpeople.LastName As PersonPlacedLName,
tpeople.Firstname As PersonPlacedFName,
tsearch.SearchNotes,
( select tpeople.Firstname  from tpeople where tpeople.guid=tSearch.RepresentativeGUID) as repfirstname, 
( select tpeople.Lastname from tpeople where tpeople.guid=tSearch.RepresentativeGUID) as replastname,
tsearch.RepresentativeGUID as RepGuid,
tposition.Position as backgroundposition,
tdepartment.Department as backgrounddepartment,
( select tpeople.Lastname from tpeople where tpeople.guid=tSearch.ReferredByGUID) as referredbylastname,
( select tpeople.FirstName from tpeople where tpeople.guid=tSearch.ReferredByGUID) as referredbylastname,
tsearch.ReferredByGUID as PersonwhorefferedGuid,
( select tcompany.CompanyName from tCompany where tCompany.guid=tSearch.PlacedFromGUID) as placedfrom,
tinstantstatustype.InstantStatus,
tWorkbench.WorkbenchName,
( select tpeople.Lastname from tpeople where tpeople.guid=tInstantStatus.PeopleGUID) as Candlastname,
( select tpeople.FirstName from tpeople where tpeople.guid=tInstantStatus.PeopleGUID) as candFirstname,
tInstantStatus.ForClientNotes,
tinstantstatus.InstantStatusNotes as InstanttatusNotesSummary,
a1.Attribute as Attributes,
a2.Attribute as Categories


from tSearch


full join tCompany on tsearch.CompanyGUID = tcompany.guid
full join tcompanylocation on tcompanylocation.guid= tcompany.LocationGUID
full join tSearchType on tsearchtype.GUID = tSearch.SearchTypeGUID
full join tSearchResult on tSearchResult.GUID = tsearch.SearchResultGUID
full join tPeople on tPeople.GUID = tsearch.PlacedGUID
full join tPosition on tPosition.GUID = tsearch.PositionGUID
full join tDepartment on tdepartment.GUID = tsearch.DepartmentGUID
full join tInstantStatus on tInstantStatus.SearchGUID = tSearch.guid
full join tInstantStatusType on tInstantStatusType.GUID = tInstantStatus.InstantStatusGUID 
full join tWorkbench on tWorkbench.SearchGUID=tsearch.GUID
full join tSearchCluendex on tSearchCluendex.CPSGUID=tsearch.GUID 
full join tAttributes AS a1 ON a1.GUID=tSearchCluendex.AttributeGUID and a1.RelatedGUID is not NULL
full join tAttributes AS a2 ON a2.GUID=tSearchCluendex.AttributeGUID and a2.RelatedGUID is NULL

它返回如下输出:

...    Attribute  |  Category

...    NULL       |  NULL
...    Programmer |  NULL
...    Secretary  |  NULL
...    Manager    |  NULL

“程序员”应该在“IT”类别中,“秘书”在“Biz Dev”等中。所以属性没问题,但没有查找类别,尽管存在 JOIN 和条件 ....

这个数据库很大,大约有 40 个表,所以我很难粘贴 SQL 结构,但希望一些聪明而善良的人能明白这一点。如果没有,请告诉我应该粘贴什么(请指定要在 MS SSMS 中执行的命令)

谢谢,

【问题讨论】:

  • 如果您希望得到多个结果,您必须为此使用JOIN。但是你会得到重复的行...
  • 重复行是可以的,只要我有相互匹配的属性和类别列。怎么做?谢谢!
  • 什么是tAttributes.RelatedGUID?如果它指向结果集的 GUID,只需添加 LEFT JOIN 并在 ON-clause 中使用此值
  • 另一个提示:如果您在连接中更频繁地使用同一个表,则必须使用名称别名。有人认为像LEFT JOIN tAttributes AS a1 ON a1.RelatedGUID=Someother.GUID。在您的选择列表中,您将获得a1.Attribute 的值。下一次调用“a2”等等...
  • @android_dev,尝试将您的( select a1.Attribute .... 替换为at.Attribute。那里不需要子选择...

标签: sql-server tsql


【解决方案1】:

CASE 语句应该可以解决问题。我们的想法是检查每条记录中的值并相应地继续,而不是寻找 null 或非 null 的记录。比如:

SELECT
(CASE WHEN tAttributes.RelatedGUID is not null then tAttributes.Attribute ELSE null END) as Attributes,
(CASE WHEN tAttributes.RelatedGUID is null then tAttributes.Attribute ELSE null END) as Categories
FROM tAttributes

【讨论】:

  • 谢谢!!!好主意....我正在检查我的数据集,但它似乎正在做它应该做的事情
【解决方案2】:

在 where 和 using CASE .. WHEN .. THEN.. 尝试以下方式添加条件..

select col1,col2,...colN..from Table where clm1 = CASE WHEN @PARAMETER = 0 THEN COL1 ELSE @PARAMETER

一旦您在 WHERE 条件中设置了相同的列名,然后如果您想作为参数传递,则从表中检索所有数据,然后根据表中的条件值检索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    • 1970-01-01
    • 2012-06-07
    相关资源
    最近更新 更多