Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL多对多关系_Sql_Sql Server - Fatal编程技术网

SQL多对多关系

SQL多对多关系,sql,sql-server,Sql,Sql Server,我在编写SQL查询时遇到困难。这是3个表的结构,表Race\u分类类型是多对多表 Table Race ---------------------------- RaceID Name Table Race_ClassificationType ---------------------------- Race_ClassificationTypeID RaceID RaceClassificationID Table RaceClassificationType ------------

我在编写SQL查询时遇到困难。这是3个表的结构,表Race\u分类类型是多对多表

Table Race
---------------------------- 
RaceID
Name

Table Race_ClassificationType
----------------------------
Race_ClassificationTypeID
RaceID
RaceClassificationID

Table RaceClassificationType
----------------------------
RaceClassificationTypeID
Name
我想做的是得到具有特定分类的种族。结果由具有表值参数的存储过程返回,该参数保存所需分类:

CREATE TYPE [dbo].[RaceClassificationTypeTable]
AS TABLE
(
  RaceClassificationTypeID INT NULL
);
GO

CREATE PROCEDURE USP_GetRaceList
    (@RaceClassificationTypeTable AS [RaceClassificationTypeTable] READONLY,
     @RaceTypeID INT = NULL,
     @IsCompleted BIT = NULL,
     @MinDateTime DATETIME = NULL,
     @MaxDateTime DATETIME = NULL,
     @MaxRaces INT = NULL)
     WITH RECOMPILE
AS
BEGIN
    SET NOCOUNT ON;

    SELECT   DISTINCT
             R.[RaceID]
            ,R.[RaceTypeID]
            ,R.[Name]
            ,R.[Abbreviation]
            ,R.[DateTime]
            ,R.[IsCompleted]
    FROM    [Race] R,[Race_ClassificationType] R_CT, [RaceClassificationType] RCT
    WHERE   (R.[RaceTypeID] = @RaceTypeID OR @RaceTypeID IS NULL)
    AND     (R.[IsCompleted] = @IsCompleted OR @IsCompleted IS NULL)
    AND     (R.[DateTime] >= @MinDateTime OR @MinDateTime IS NULL)
    AND     (R.[DateTime] <= @MaxDateTime OR @MaxDateTime IS NULL)
    AND     (R.RaceID = R_CT.RaceID)
    AND     (R_CT.RaceClassificationTypeID = RCT.RaceClassificationTypeID)
    AND     (RCT.RaceClassificationTypeID IN (SELECT DISTINCT T.RaceClassificationTypeID FROM @RaceClassificationTypeTable T))
    ORDER BY [DateTime] DESC
    OFFSET 0 ROWS FETCH NEXT @MaxRaces ROWS ONLY
END
GO
RaceClassificationTypeTable参数中的RaceClassificationTypeId:3和8

输出:RaceClassificationID3和8的所有比赛,以及可选的任何其他比赛(2、29、12)

这意味着只应返回种族92729和92730,因为示例中的所有种族都将返回。

这是“集合中的集合”子查询的示例。解决这个问题的一种方法是使用聚合和
具有
子句。以下是获得
RaceId
s的方法:

select RaceID
from RaceClassification rc
group by RaceID
having sum(case when RaceClassificationTypeId = 3 then 1 else 0 end) > 0 and
       sum(case when RaceClassificationTypeId = 8 then 1 else 0 end) > 0;
having
子句中的每个条件都计算每种类型有多少行。只保留与每个的比赛(因为
>0

您可以使用此作为子查询来获取所有比赛信息:

select r.*
from Races r join
     (select RaceID
      from RaceClassification rc
      group by RaceID
      having sum(case when RaceClassificationTypeId = 3 then 1 else 0 end) > 0 and
             sum(case when RaceClassificationTypeId = 8 then 1 else 0 end) > 0
     ) rc
     on r.RaceID = rc.RaceId;

您的存储过程似乎有其他条件。这些也可以添加进去。

我已经设置了两个表,一个存储结果集,另一个表示存储过程的表值参数中的值。见下文

CREATE TABLE ABC
(
RCTID INT,
RID INT
)
INSERT INTO ABC VALUES (3,92728)
INSERT INTO ABC VALUES (3,92729)
INSERT INTO ABC VALUES (8,92729)
INSERT INTO ABC VALUES (29,92729)
INSERT INTO ABC VALUES (12,92729)
INSERT INTO ABC VALUES (2,92729)
INSERT INTO ABC VALUES (3,92730)
INSERT INTO ABC VALUES (8,92730)
INSERT INTO ABC VALUES (8,92731)
INSERT INTO ABC VALUES (1,92731)
GO
CREATE TABLE TABLEVALUEPARAMETER
(
VID INT
)
INSERT INTO TABLEVALUEPARAMETER VALUES (3)
INSERT INTO TABLEVALUEPARAMETER VALUES (8)
GO
SELECT RID FROM ABC WHERE RCTID IN (SELECT VID FROM TABLEVALUEPARAMETER) GROUP BY
RID HAVING COUNT(RID) = (SELECT COUNT(VID) FROM TABLEVALUEPARAMETER)
GO
如果你在你的机器上运行它,你会注意到它会产生你想要的两个ID

因为您有一个选择了很多列的存储过程,所以有必要使用CTE(公共表表达式)。这是因为如果要尝试对当前select语句中的所有列进行分组,则必须按所有列进行分组,然后会得到重复

如果第一个CTE提供结果集,然后您使用上面选择的版本,那么您应该能够只生成您想要的ID

如果你不知道,让我知道

CREATE TABLE ABC
(
RCTID INT,
RID INT
)
INSERT INTO ABC VALUES (3,92728)
INSERT INTO ABC VALUES (3,92729)
INSERT INTO ABC VALUES (8,92729)
INSERT INTO ABC VALUES (29,92729)
INSERT INTO ABC VALUES (12,92729)
INSERT INTO ABC VALUES (2,92729)
INSERT INTO ABC VALUES (3,92730)
INSERT INTO ABC VALUES (8,92730)
INSERT INTO ABC VALUES (8,92731)
INSERT INTO ABC VALUES (1,92731)
GO
CREATE TABLE TABLEVALUEPARAMETER
(
VID INT
)
INSERT INTO TABLEVALUEPARAMETER VALUES (3)
INSERT INTO TABLEVALUEPARAMETER VALUES (8)
GO
SELECT RID FROM ABC WHERE RCTID IN (SELECT VID FROM TABLEVALUEPARAMETER) GROUP BY
RID HAVING COUNT(RID) = (SELECT COUNT(VID) FROM TABLEVALUEPARAMETER)
GO