0

我想不出一个更好的问题来解决这个问题,但就是这样。我在多对多关系中有 3 个表,例如:

学生 -> StudentTasks <- 任务

学生任务有一个名为“标记”的列,当创建学生时,为可能的任务创建记录,标记 = 0,例如:

Student ---------

Given 
  "StudentA -> Id = 1"

Tasks ------------

Given 
  "Task A -> Id = 1"
  "Task B -> Id = 2"


StudentTasks ------

StudentId -- TaskId -- Marked

1         --   1    --    0

1         --   2    --    0

我需要为学生任务中的每一行设置变量@TaskA、@TaskB 和各自的“标记”值,这样我就可以用它更新另一个表的列。

解决问题的另一种方法是直接更新表,因此在相同的情况下,但添加了如下表:

StudentId -- TaskA -- TaskB

我希望看到它像这样填充:

StudentId -- TaskA -- TaskB

1         --   0   --   0

如果我们有“StudentB -< Id = 2”,TaskB 标记为 1,我们将有:

StudentId -- TaskA -- TaskB

1         --   0   --   0

2         --   0   --   1

我这样做的方式根本没有效率,它需要 40 秒才能浏览 3300 条记录(我正在使用光标浏览学生列表),欢迎提出任何建议。

更新:

使用@djangojazz 对自提取查询所做的想法

DECLARE @Student TABLE ( StudentID INT IDENTITY, Name VARCHAR(50));

INSERT INTO @Student VALUES ('Brett'),('Sean')

DECLARE @StudentTasks TABLE (StudentID INT, TaskId INT, Marked BIT);

INSERT INTO @StudentTasks VALUES (1,1,0),(1,2,0),(2,1,0),(2,2,1)

DECLARE @Tasks TABLE (TaskID INT IDENTITY, NAME VARCHAR(50));

INSERT INTO @Tasks VALUES ('Study'),('Do Test')


SELECT * FROM @Student
SELECT * FROM @StudentTasks
SELECT * FROM @Tasks

-- 这就是我需要的结果

DECLARE @ResultTable TABLE (StudentId INT, Study BIT, DoTest BIT);

INSERT INTO @ResultTable VALUES (1,0,0),(2,0,1)

SELECT * FROM @ResultTable
4

2 回答 2

1

2013 年 6 月 13 日更新。我什至认为您不需要立即使用“学生”表,因为您只想以标识符为中心。但是,如果您将来对任何事物使用重复值,则问题可能会出现,这种逻辑将被打破。这意味着,如果您有一个表,其中学生 ID 可能会针对另一个类型而不是位的值重复,那么您将需要执行更多操作来查看哪个是最新的身份等。这么说虽然我可以给你你说你想要的。

DECLARE @Student TABLE ( StudentID INT IDENTITY, Name VARCHAR(50));

INSERT INTO @Student VALUES ('Brett'),('Sean')

DECLARE @StudentTasks TABLE (StudentID INT, TaskId INT, Marked BIT);

INSERT INTO @StudentTasks VALUES (1,1,0),(1,2,0),(2,1,0),(2,2,1)

DECLARE @Tasks TABLE (TaskID INT IDENTITY, NAME VARCHAR(50));

INSERT INTO @Tasks VALUES ('Study'),('Do Test')

DECLARE @ResultTable TABLE (StudentId INT, Study BIT, DoTest BIT);

INSERT INTO @ResultTable VALUES (1,0,0),(2,0,1)

select 'Results you wanted'
SELECT * 
FROM @ResultTable

select 'Method A'
;


-- with case when forcing a pivot on an expression
With x as 
    (
    select
        st.StudentID
    ,   cast(st.Marked as tinyint) as Marked
    ,   t.NAME
    from @StudentTasks st 
        join @Tasks t on st.TaskId = t.TaskID
    )
Select
    x.StudentID
,   max(case when NAME = 'Study' then Marked end) as Study
,   max(case when NAME = 'Do Test' then Marked end) as DoTest
FROM x
group by x.StudentID

Select 'Method B'
;

-- with traditional pivot you need to translate names I believe
With x as 
    (
    select
        st.StudentID
    ,   cast(st.Marked as tinyint) as Marked
    ,   case when t.NAME = 'Study' then 0 else 1 end as Name
    from @StudentTasks st 
        join @Tasks t on st.TaskId = t.TaskID
    )
Select
    pvt.StudentID
,   [0] as Study
,   [1] as 'Do Test'
FROM x
    pivot(max(x.Marked) for x.Name in ([0], [1])) as pvt
于 2013-06-12T23:24:16.903 回答
0

PIVOT 2 个任务 A 和 B 的 StudentTasks 表,将其与 StudentID 上的“附加表”一起加入并更新它..

于 2013-06-12T21:49:08.510 回答