Отображение строк SQL SELECT в табличном представлении - PullRequest
0 голосов
/ 09 мая 2018

Структура моей базы данных и пример данных:

CREATE TABLE [dbo].[users] (
    [user_id] [bigint] IDENTITY(1,1) NOT NULL,
    [user_name] [nvarchar](50) NULL,
    [first_name] [nvarchar](50) NULL,
    [last_name] [nvarchar](50) NULL,
    [id_number] [nvarchar](50) NULL,
    CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED 
    (
        [user_id] ASC
    )
)

insert into users (user_name, first_name, last_name, id_number)
select 'user1','John','Brown',7707071231
union all
select 'user2','Mary','Jane',7303034432
union all
select 'user3','Peter','Pan',5503024441


CREATE TABLE [dbo].[quiz_results] (
    [result_id] [bigint] IDENTITY(1,1) NOT NULL,
    [quiz_id] [bigint] NOT NULL,
    [user_id] [bigint] NOT NULL,
    [grade] [bigint] NULL,
    CONSTRAINT [PK_quizresults] PRIMARY KEY CLUSTERED 
    (
        [result_id] ASC
    )
)

insert into quiz_results (quiz_id, user_id, grade)
select 1,1,88
union all
select 2,1,84
union all
select 3,1,33
union all
select 1,2,65

Этот запрос дает мне результаты теста для user_id = 1:

SELECT
    users.first_name + ' ' + users.last_name + ' (' + users.id_number + ')' AS student_name,
    quiz.quiz_name,
    quiz_results.grade
FROM quiz_results 
INNER JOIN quiz ON quiz_results.quiz_id = quiz.quiz_id
INNER JOIN users ON quiz_results.user_id = users.user_id
WHERE users.user_id = 12345

как это:

+-------------------------+-----------+-------+
|      student_name       | quiz_name | grade |
+-------------------------+-----------+-------+
| John Brown (7707071231) |  quiz a   |  88   |
| John Brown (7707071231) |  quiz b   |  84   |
| John Brown (7707071231) |  quiz c   |  33   |
+-------------------------+-----------+-------+

Но я не хочу, чтобы имя студента отображалось в каждой строке. Я хочу этот вывод:

+-------------------------+
| John Brown (7707071231) | 
+-------------------------+
|   quiz a    |     88    |
|   quiz b    |     84    |
|   quiz c    |     33    |
+-------------------------+

Имя студента находится в первом ряду, за которым следует по одному ряду для каждого результата теста - я специально хочу имя студента в первом ряду.

Запрос будет только для одного имени студента. По сути, я хочу создать «сертификат» непосредственно в SQL.

Каков наилучший способ SQL получить данные в этом формате? Будет ли работать команда CTE или STUFF ()? Или есть лучший способ?

1 Ответ

0 голосов
/ 10 мая 2018

Это просто невозможно сделать в SQL.
SQL может возвращать только скалярные значения или наборы результатов (табличные данные), а наборы результатов не поддерживают «диапазон столбцов» - поэтому единственный способ сделать это - на уровне представления, - но вы можете сделать некоторые вещи в SQL Server, чтобы сделать Ваша работа на уровне представления проще.

Один из вариантов - создать хранимую процедуру, которая будет возвращать имя студента в качестве выходного параметра и оценки теста в виде набора результатов:

CREATE PROCEDURE GetQuizResultByUserId
(
    @UserId int,
    @UserName nvarchar(154) OUTPUT 
)
AS

-- it's 154 because    50     +  1  +     50    +  2   +     50     + 1
SELECT @UserName = first_name + ' ' + last_name + ' (' + id_number + ')'
FROM users
WHERE user_id = @UserId


SELECT
quiz.quiz_name,
quiz_results.grade
FROM quiz_results 
INNER JOIN quiz ON quiz_results.quiz_id = quiz.quiz_id
WHERE quiz_results.user_id = @UserId

GO

Другой вариант, поскольку это версия 2016 года, - возвращать результаты в формате Json, используя предложение For Json:

SELECT first_name + ' ' + last_name + ' (' + id_number + ')' As UserName,
       (
          SELECT quiz.quiz_name,
                 quiz_results.grade
          FROM quiz_results 
          INNER JOIN quiz ON quiz_results.quiz_id = quiz.quiz_id
          WHERE quiz_results.user_id = @UserId
          FOR JSON AUTO
       ) As quizResult
FROM users
WHERE user_id = @UserId
FOR JSON AUTO

Результат следующий json:

[
  {
    "UserName": "John Brown (7707071231)",
    "quizResult": [
      {
        "quiz_name": "quiz a",
        "grade": 88
      },
      {
        "quiz_name": "quiz b",
        "grade": 84
      },
      {
        "quiz_name": "quiz c",
        "grade": 33
      }
    ]
  }
]
...