【问题标题】:SQL Server stored procedure - Is it possible to return multiple results within a field of each rowSQL Server 存储过程 - 是否可以在每行的一个字段中返回多个结果
【发布时间】:2017-05-17 21:30:28
【问题描述】:

我想知道是否有可能在每行的一列中返回多个结果,或者是在一列中获得多个结果的最佳方式。

例如,如果您有一个将返回多个学生的存储过程,但学生表中的一列是照片 ID。一个学生可以有几张照片,但是这个存储过程需要返回每个学生的所有三个照片 ID。

SELECT 
    S.Name AS Name,
    (SELECT S.Id FROM COURSES WHERE P.StudentId = S.Id) AS PhotoId
FROM 
    PHOTOS P
INNER JOIN 
    PHOTOS P ON P.StudentId = S.Id

上面的例子不起作用,但我需要知道什么是最好的方法。由于图片的最大数量设置为 3,我想在单独的列中创建每个照片 ID,如下所示。

SELECT 
    S.Name AS Name,
    (SELECT TOP 1 S.Id FROM COURSES WHERE P.StudentId = S.Id) AS PhotoId1,
    (SELECT TOP 2 S.Id FROM COURSES WHERE P.StudentId = S.Id) AS PhotoId2,
    (SELECT TOP 3 S.Id FROM COURSES WHERE P.StudentId = S.Id) AS PhotoId3
FROM 
    PHOTOS P
INNER JOIN 
    PHOTOS P ON P.StudentId = S.Id

在这种情况下,只有第一行有效。而不是使用TOP 2TOP 3 相当于只取第二个和第三个结果(与Linq Take(1)Skip(1) 相同)。

或者有更好的方法吗?此外,我必须确保每个学生只返回一次,即使他们有多个图像

【问题讨论】:

    标签: sql sql-server stored-procedures


    【解决方案1】:

    我不确定您希望以哪一种方式来构造数据,其中包含一行中的照片或不同列中的照片。然而,行对我来说似乎更自然。

    SELECT  ph.Name 
          , PhotoId = co.Id
    
    FROM    dbo.Photos      (NOLOCK)     ph
    JOIN    dbo.Courses     (NOLOCK)     co ON co.Id = ph.StudentId
    

    输出:

    姓名 |照片编号

    爱德华 |第1234章

    爱德华 |第2345章

    爱德华 |第3456章



    更新

    ;WITH CTE AS(
                SELECT  ph.Name 
                      , PhotoId =   co.Id
                      , RN      =   ROW_NUMBER()OVER(PARTITION BY ph.Name ORDER BY co.Id)
    
                FROM    dbo.Photos      (NOLOCK)     ph
                JOIN    dbo.Courses     (NOLOCK)     co ON co.Id = ph.StudentId
            )
    
    SELECT  Name 
          , PhotoId1 = SUM(CASE WHEN RN = 1 THEN Id ELSE NULL END)  
          , PhotoId2 = SUM(CASE WHEN RN = 2 THEN Id ELSE NULL END)  
          , PhotoId3 = SUM(CASE WHEN RN = 3 THEN Id ELSE NULL END)  
    
    FROM CTE
    
    GROUP BY Name
    

    【讨论】:

    • 第一个例子和你的完全一样。不幸的是,我需要它的另一种方式。一个学生只能在一行中显示他/她的所有照片 ID
    • 在这种情况下,我建议使用 ROW_NUMBER 函数创建 CTE 来帮助调整您的 PhotoId。
    【解决方案2】:

    尝试使用 row_number 获取 1、2 和 3 张照片

    SELECT S.Name AS Name
    ,(select x.photo_id from (SELECT PHOTO_ID, row_number() over (order by photo_id) row_num  from PHOTOS P where p.student_id = s.studenT_id) x where x.row_num = 1) AS PhotoId1
    ,(select x.photo_id from (SELECT PHOTO_ID, row_number() over (order by photo_id) row_num  from PHOTOS P where p.student_id = s.studenT_id) x where x.row_num = 2) AS PhotoId2
    ,(select x.photo_id from (SELECT PHOTO_ID, row_number() over (order by photo_id) row_num  from PHOTOS P  where p.student_id = s.studenT_id) x where x.row_num = 3) AS PhotoId3
    FROM STUDENTS S
    

    【讨论】:

    • 似乎是个好主意,但它不起作用。我得到的错误消息是Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. 另外我需要提到这个存储过程已经使用row_number(),但我想这应该没关系。如果语句是正确的,它应该只返回一个结果,我检查了数据库
    • 不再需要分区,所以只需按顺序订购.. 查看更新的脚本
    • 我使用了两种方式的命令,仍然没有得到正确的结果。它确实获取所有图像,但是为每个结果创建一个新行
    猜你喜欢
    • 2019-06-20
    • 1970-01-01
    • 2023-04-03
    • 2020-05-01
    • 2010-09-27
    • 2017-02-14
    • 2014-05-22
    • 1970-01-01
    • 2011-04-22
    相关资源
    最近更新 更多