Скомпилировать все значения из нескольких строк с разделителями в таблицу - PullRequest
1 голос
/ 03 марта 2020

Я собираю ответы на форму онлайн-опроса в виде таблицы:

CREATE TABLE [Survey]
(
    ID int IDENTITY(1,1) NOT NULL,
    UserName varchar(50) NOT NULL,
    Responses varchar(max) NOT NULL,
    Taken datetime NOT NULL
)

Когда пользователь нажимает кнопку отправки, процесс захватывает все отмеченные флажки и объединяет их имена в строка с разделителями и вставка в таблицу вместе с другими полями. По сути, такой же как:

INSERT INTO [Survey] (UserName, Responses, Taken) VALUES ('John', 'chkSize', GetDate())
INSERT INTO [Survey] (UserName, Responses, Taken) VALUES ('Mary', 'chkSquare;chkSoft', GetDate())
INSERT INTO [Survey] (UserName, Responses, Taken) VALUES ('Steve', 'chkSize;chkYellow;chkRound', GetDate())
INSERT INTO [Survey] (UserName, Responses, Taken) VALUES ('April', 'chkRound;chkStacked;chkFiltered;chkBrown', GetDate())

Есть ли способ легко go просмотреть все "Ответы" для всей таблицы, найти все возможные значения, а затем вернуть их в виде списка Уникальность в их собственной таблице ? то есть:

chkBrown
chkFiltered
chkRound
chkSize
chkSoft
chkSquare
chkStacked
chkYellow

Ответы [ 2 ]

5 голосов
/ 03 марта 2020

Вы можете делать, что хотите, используя string_split():

select s.value, count(*)
from survey su cross apply
     string_split(su.responses, ';') s
group by s.value;

Здесь - это дБ <> скрипка.

Тот факт, что вы можете сделать это не значит, что вам следует . Вы должны хранить ответы в отдельной таблице , по одной строке для каждого ответа.

0 голосов
/ 03 марта 2020

Если это просто одна страница, установите флажок только для опроса, один из подходов будет

// declare flags enum
[Flags]
public enum Checkboxes : int
{
    none = 0,
    chkBrown = 1,
    chkFiltered = 2,
    chkRound = 4,
    chkSize = 8,
    chkSoft = 16,
    chkSquare = 32,
    chkStacked = 64,
    chkYellow = 128
}
// on initialize/constructor add these values to your checkbox tag
chkBrown.Tag = Checkboxes.chkBrown ;

// Add checkbox extension
public shared Checkboxes GetCode(this Checkbox cb)
{
    if (cb.Checked)
         return (Checkboxes)cb.Tag;
    return Checkboxes.none;
}

// your db value would be 
Checkboxes val = chkBrown.GetCode() | chkFiltered() . . . // list all c-boxes here

// make db field integer and save this value: 
(int)val

Но ... еще раз. Это хорошо только в том случае, если никаких изменений не потребуется, и система настроена на c. Кажется, это домашняя работа, а не долгосрочная проблема. Но в таких случаях долгосрочный сценарий представляет собой таблицу «многие ко многим», в которой можно разместить несколько записей для одного и того же вопроса в виде отдельной записи. Таким образом, SQL поиск прост

Здесь работает скрипка, где вы также можете увидеть, как установить флажок на значение, полученное из числа

using System;


public class ClsVal// instead of checkbox
{

   public bool A {get; set;}
   public Checkboxes C {get; set;}
}

public static class ClsValExt
{

    public static Checkboxes GetCode(this ClsVal cb)
    {
        if (cb.A)
             return (Checkboxes)cb.C;
        return Checkboxes.none;
    }
}


[Flags]
public enum Checkboxes : int
{
    none = 0,
    chkBrown = 1,
    chkFiltered = 2,
    chkRound = 4,
    chkSize = 8,
    chkSoft = 16,
    chkSquare = 32,
    chkStacked = 64,
    chkYellow = 128
}



public class Program
{
    public static void Main()
    {

        var c1 = new ClsVal() {A = true, C = Checkboxes.chkBrown};
        var c2 = new ClsVal() {A = true, C = Checkboxes.chkFiltered};
        var c3 = new ClsVal() {A = false, C = Checkboxes.chkRound};
        var c4 = new ClsVal() {A = true, C = Checkboxes.chkSize};

        var x = c2.GetCode() | c1.GetCode() | c3.GetCode() | c4.GetCode();
        var i = (int)x;
        Console.WriteLine(i);

        Console.WriteLine((x & Checkboxes.chkBrown) == Checkboxes.chkBrown); //Yes
        Console.WriteLine((x & Checkboxes.chkBrown) == Checkboxes.chkYellow);  // No
    }
}
...