这是我今天的第二个SQL问题 - 我在DBA的东西上有点新手......
我正在尝试将一个复杂的SQL查询连接在一起,将大约12个表中的数据合并为1个单独的表。虽然数据库中有一对多关系,但我知道每个关系的最大数量。
所以,我(使用堆栈溢出的帮助!)展平了我的数据库的第一级,并且有一对查询,现在必须将它们连接在一起:
(删节)
SELECT
A.StudentId, C1.Topic AS SIoC1, C1.Level AS SIoCScore1
FROM Assessment A
LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1
WHERE A.Type = 'School'
SELECT
A.StudentId, C1.Topic AS PIoC1, C1.Level AS PIoCScore1
FROM Assessment A
LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1
WHERE A.Type = 'Parent'
是否可以将查询命名为别名?
或者我如何加入这两个查询,以便输出如下:
| A.Id | SIoC1 | SIoCScore1 | PIoC1 | PIoCScore1 |
**更新** 其背后的领域是进行评估,学校和家长必须在其上进行报告。因此,单行标识一个评估,其中包含School和Parent值。
我正在使用SQL Server 2005。
谢谢!
*进一步更新* 这个查询似乎可以完成这项工作......
SELECT PreConcerns.StudentId, TIoC1, TIoCScore1, PIoC1, PIoCScore1
FROM
Assessment PreConcerns
LEFT OUTER JOIN
(
SELECT
P.StudentId, C1.Topic AS TIoC1, C1.Level AS TIoCScore1
FROM Assessment P
LEFT JOIN Concern C1 ON P.Id = C1.Assessment_Id and C1.TopicNumber = 1
WHERE P.Type = 'School'
) scons
ON scons.StudentId= PreConcerns.StudentId
LEFT OUTER JOIN
(
SELECT
P.StudentId, C1.Topic AS PIoC1, C1.Level AS PIoCScore1
FROM Assessment P
LEFT JOIN Concern C1 ON P.Id = C1.Assessment_Id and C1.TopicNumber = 1
WHERE P.Type = 'Parent'
) pcons
ON pcons.StudentId = PreConcerns.StudentId
进一步更新(拍2张!) ** (我不确定我是否应该重新开启这个问题?) 我今天回到工作岗位,发现上面的'解决方案'并没有完全解决问题 - 它为每次评估创建了两行。
回顾一下,我有以下表格:
Student (int:id, varchar(50):name)
Assessment (int:id, date:date, int:StudentId, )
Concern (int:id, int:assessment_id, varchar(20):topic, int:level)
因此,对于系统中的每个学生,只有两个评估 - 一个类型为“学校”,另一个类型为“父母”。
我想创建一个结合评估和关注点的行:
(伪列:)
| Assessment.StudentId | SchoolConcernTopic | SchoolConcernLevel | ParentConcernTopic | ParentConcernLevel |
或来自上面的sql:
| PreConcerns.StudentId | SIoC1 | SIoCScore1 | PIoC1 | PIoCScore1 |
每个学生只填充一行,结合两种评估。 我有这个结构使用上面的SQL,但它返回两行!我无法弄清楚如何更新这个只返回一个 - 任何帮助感激收到!!
一如既往地谢谢!
答案 0 :(得分:4)
这可以通过一个查询来完成。 IN子句只是一种说A.Type = 'School' OR A.Type = 'Parent'
SELECT
A.Id, C1.Topic AS PIoC1, C1.Level AS PIoCScore1
FROM Assessment A
LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1
WHERE A.Type IN ('School','Parent')
答案 1 :(得分:2)
<击>
确保在第一个查询中指定了所需的字段名称,然后UNION ALL
两个查询;如果你想在另一端的结尾标记一组结果。
忽略我的第一个答案,我正在服用垃圾,因为这不会得到你想要的结果。遗憾。
如果您希望输出包含重复列,SIoC1
和PIoC1
基本相同,但名称不同,具体取决于该行是来自“学校”还是“家长”,那么结果集将以NULLS结束,例如(随机数据,因为您不提供样本数据)
| A.Id | SIoC1 | SIoCScore1 | PIoC1 | PIoCScore1 |
1 A 10 NULL NULL -- Row type 'School'
2 NULL NULL B 20 -- Row type 'Parent'
etc. etc.
如果数据存储在同一个表中,则使用相同的字段名称使用其他字段来区分行,例如Type
,并在结果中显示该行。
答案 2 :(得分:2)
一个查询可能就足够了:
SELECT
A.Id, A.Type, C1.Topic AS IoC1, C1.Level AS IoCScore1
FROM Assessment A
LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1
WHERE A.Type IN ('School', 'Parent')
答案 3 :(得分:2)
我认为此查询必须返回与“进一步更新”部分中的结果相同的结果。
P.Type = ...
条件已从WHERE移动到ON部分,因此您无需借助加入子选择即可获得所需的效果。
SELECT
P.StudentId,
CS.Topic AS TIoC1,
CS.Level AS TIoCScore1,
CP.Topic AS PIoC1,
CP.Level AS PIoCScore1
FROM
Assessment P
LEFT JOIN Concern CS ON P.Id = CS.Assessment_Id
and CS.TopicNumber = 1 and P.Type = 'School'
LEFT JOIN Concern CP ON P.Id = CP.Assessment_Id
and CP.TopicNumber = 1 and P.Type = 'Parent'
编辑:似乎分组应该有帮助。 (我将离开我的初始查询,因此更容易看到更新要求的必要更改。)
SELECT
P.StudentId,
MAX(CS.Topic) AS TIoC1,
MAX(CS.Level) AS TIoCScore1,
MAX(CP.Topic) AS PIoC1,
MAX(CP.Level) AS PIoCScore1
FROM
Assessment P
LEFT JOIN Concern CS ON P.Id = CS.Assessment_Id
and CS.TopicNumber = 1 and P.Type = 'School'
LEFT JOIN Concern CP ON P.Id = CP.Assessment_Id
and CP.TopicNumber = 1 and P.Type = 'Parent'
GROUP BY P.StudentId
答案 4 :(得分:1)
您可以在一个查询中选择所有内容,并使用CASE
语句仅填充适用的值
SELECT
A.Id,
CASE A.Type
WHEN 'School'
THEN C1.Topic
ELSE NULL
END
AS SIoC1,
CASE A.Type
WHEN 'School'
THEN C1.Level
ELSE NULL
END
AS SIoCScore1,
CASE A.Type
WHEN 'Parent'
THEN C1.Topic
ELSE NULL
END
AS PIoC1,
CASE A.Type
WHEN 'Parent'
THEN C1.Level
ELSE NULL
END AS PIoCScore1
FROM Assessment A
LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1
WHERE A.Type IN ('School', 'Parent')
编辑最好存储“类型”列,以便区分所需的两种类型的数据,然后就不必重复上述示例中的列。如果要创建一个表,然后使其符合某种形式的规范化,则不希望重复列,但是如果在VIEW中使用此select语句,那么这样做是可以接受的。
答案 5 :(得分:0)
结果列名必须相同(使用的别名)和相同的数据类型:
SELECT
A.Id, C1.Topic AS Topic, C1.Level AS Level
FROM Assessment A
LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1
WHERE A.Type = 'School'
UNION
SELECT
A.Id, C1.Topic AS Topic, C1.Level AS Level
FROM Assessment A
LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1
WHERE A.Type = 'Parent'
答案 6 :(得分:0)
SELECT
A.Id,
CASE A.Type
WHEN 'School'
THEN C1.Topic
ELSE NULL
END
AS SIoC1,
CASE A.Type
WHEN 'School'
THEN C1.Level
ELSE NULL
END
AS SIoCScore1,
CASE A.Type
WHEN 'Parent'
THEN C1.Topic
ELSE NULL
END
AS PIoC1,
CASE A.Type
WHEN 'Parent'
THEN C1.Level
ELSE NULL
END AS PIoCScore1
FROM Assessment A
LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1
WHERE A.Type IN ('School', 'Parent')
答案 7 :(得分:0)
试试这个解决方案
SELECT * INTO #School FROM
(
SELECT
A.StudentId, C1.Topic AS SIoC1, C1.Level AS SIoCScore1
FROM Assessment A
LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1
WHERE A.Type = 'School'
)school
SELECT * INTO #Parent FROM
(
SELECT
A.StudentId, C1.Topic AS PIoC1, C1.Level AS PIoCScore1
FROM Assessment A
LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1
WHERE A.Type = 'Parent'
)parent
SELECT
SL.StudentId
,SL.SIoC1
,SL.SIoCScore1
,PT.PIoC1
,PT.PIoCScore1
From #School SL
LEFT JOIN #Parent PT ON PT.StudentId = SL.StudentId