SQL Server 中的 SUBQUERY 和 EXISTS

Posted

技术标签:

【中文标题】SQL Server 中的 SUBQUERY 和 EXISTS【英文标题】:SUBQUERY and EXISTS in SQL Server 【发布时间】:2018-11-16 17:07:14 【问题描述】:

我正在运行以下查询,它从tblFamilytblConstituent 返回结果集中的所有列。

SELECT
    *
FROM
    tblFamily AS f
WHERE
    DataProviderID = 23
    AND ISNULL(UsesIndexMarker, 0) = 0
    AND EXISTS (SELECT 1
                FROM tblConstituent
                WHERE FamilyID = f.FamilyID
                  AND StartDate < GETDATE()
                  AND EndDate > GETDATE()
                  AND FilterValue LIKE '%-%-%');

现在,我只想要来自tblFamilytblConstituent 的结果集中的选定/少数列,如下所示。但是当我运行时,我可以从 tblFamily 获取列,但无法从 tblConstituent 获取任何列。

SELECT
    td.FamilyID, 
    td.Name,
    td.DataProviderID,
    td.UsesIndexMarker,
    td.OpenDate,
    td.ListingID
FROM
    (SELECT *
     FROM tblFamily AS f
     WHERE DataProviderID = 23
       AND ISNULL(UsesIndexMarker, 0) = 0
       AND EXISTS (SELECT 1
                   FROM tblConstituent AS tc
                   WHERE tc.FamilyID = f.FamilyID
                     AND tc.StartDate < GETDATE()
                     AND tc.EndDate > GETDATE()
                     AND tc.FilterValue LIKE '%-%-%'
                     AND f.DataProviderID = 23
                     AND ISNULL(f.UsesIndexMarker, 0) = 0)) AS td;

知道为什么当我运行第一个查询时所有数据都可用时,我无法从tblConstituent 获取数据吗?我收到此错误:

消息 207,第 16 层,状态 1,第 79 行 列名“ListingID”无效

希望我的问题很清楚。

谢谢。

PS:表格定义如下:

tblFamily

FamilyID    int
RefFamilyID int
FamilyTypeID    int
Name    varchar
DataProviderID  int
CalendarID  int
TrustedPrices   tinyint
FXRateSetID int
CurrentDate date
LastRevision    bigint
HasClose    tinyint
HasOpen tinyint
HasTPlus    tinyint
OffsetFromMaxAsAtDate   tinyint
PriceSetID  int
DividendSetID   int
CorporateActionSetID    int
IncludeFilterInNaturalKey   tinyint
MatchAllCodes   tinyint
CodeReferenceFamilyID   int
LatestTaskRunID int
TrustedFXRates  tinyint
HasDividends    tinyint
HasPrices   tinyint
HasRebalance    tinyint
HasReferenceData    tinyint
HasIntradayChanges  tinyint
TplusDataIsDelta    tinyint
ValidateAfterPersisting tinyint
LastUpdate  datetime
FundProviderID  int
TimeDataExpires time
ExcludeZeroNumberOfUnits    bit
PrefilterConstituents   bit
LimitEndDate    bit
IgnoreForPricing    bit
ExcludedAssetSetID  int
NextRebalanceDate   date
TaxRateSetID    int
OpenDataIsDelta bit
RebalanceDataIsDelta    bit
OpenDate    date
AutoAddMissingListing   bit
EnforcedSecurityTypeID  int
TplusDataIsCummulative  bit
CalculationSetID    int
ValidationSetID int
UsesIndexMarker bit
MappingReferenceFamilyID    int
DataExtractionSetID int
MappingReferenceSecurityID  int
AutoAddOddLots  bit
DefaultFilterValue  varchar
SecurityClassID int
CountryClassificationID int
DataStatusMask  int
RebalanceFrequency  varchar
RebalanceNotes  varchar
NextRebalanceDataAvailable  date
CheckFileDates  bit
IsPayDateUseForReinvestment int
ValidationThresholdSetID    int
Created datetime

和表tblConstituent

ConstituentID   bigint
FamilyID    int
ListingID   int
StartDate   date
EndDate date
FilterValue varchar
ConstituentType tinyint
NumberOfUnits   decimal
PriceAdjustmentFactor   decimal
Factor1 decimal
Factor2 decimal
Factor3 decimal
Factor4 decimal
Factor5 decimal
Factor6 decimal
Factor7 decimal
Factor8 decimal
Factor9 decimal
IsGettingArchived   tinyint

【问题讨论】:

没有任何表定义,这只是猜测。请发布您的表格的详细信息,这样我们就不必猜测了。 只是为了扩展@SeanLange 所说的内容,我们不知道任一表中的列是什么,因为您没有告诉我们。 Start Here 根据需要编辑您的问题。 @EricBrandt 根据您和 Sean 的要求更新了问题。谢谢 现在仔细观察,我将挑战您发布的第一个查询返回来自tblConstituent 的任何列的断言。它仅存在于相关的子查询中。为了让它的列出现在结果集中,它必须出现在某种JOIN 中。 立即在您的子查询中添加 2 个过滤条件,它们是 tblFamily 的一部分;它们是 AND f.DataProviderID = 23 AND ISNULL(f.UsesIndexMarker, 0) = 0 。如果您的时间紧迫,请使用您的第一个查询并插入临时表或表变量,然后从临时表/变量中进行最终选择并挑选出您需要的列。 【参考方案1】:

你是对的Zeki Gumus。

但是下面不需要加入equalevents

    AND f.DataProviderID = 23
    AND ISNULL(f.UsesIndexMarker, 0) = 0

“在哪里”存在它们

【讨论】:

【参考方案2】:

您不能将ListingId 列在列表中,因为您将tblConstituent 与EXISTS 一起使用而不是JOIN。请检查以下查询,我相信这就是您想要的:

SELECT  F.FamilyID, 
        F.Name,
        F.DataProviderID,
        F.UsesIndexMarker,
        F.OpenDate,
        TC.ListingID
FROM    tblFamily AS f
INNER JOIN tblConstituent AS tc
                   ON tc.FamilyID = f.FamilyID
                     AND tc.StartDate < GETDATE()
                     AND tc.EndDate > GETDATE()
                     AND tc.FilterValue LIKE '%-%-%'
                     AND f.DataProviderID = 23
                     AND ISNULL(f.UsesIndexMarker, 0) = 0

我刚刚注意到我们不需要这部分。谢谢卡达斯。

--WHERE DataProviderID = 23
--AND       ISNULL(F.UsesIndexMarker, 0) = 0

【讨论】:

以上是关于SQL Server 中的 SUBQUERY 和 EXISTS的主要内容,如果未能解决你的问题,请参考以下文章

SQL:请改进我的 select-where-subquery-returns-one 查询

sql 包含于语法

MySQL Subquery Summary

sql server with as 能提高性能吗

MySQL Left Join Subquery with *

MySQL--5--subquery和连接