将多个分隔字符串中的所有值编译成 table
Compile all values across multiple delimited strings into a table
我正在 table 中收集对在线调查表的回复,如下所示:
CREATE TABLE [Survey]
(
ID int IDENTITY(1,1) NOT NULL,
UserName varchar(50) NOT NULL,
Responses varchar(max) NOT NULL,
Taken datetime NOT NULL
)
当用户点击提交按钮时,一个进程会抓取所有被点击的复选框并将它们的名称连接成一个分隔字符串,并将其与其他字段一起填充到 table 中。基本相同:
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())
有没有一种方法可以轻松地遍历整个 table 的所有 "Responses",找到所有可能的值,然后 return 它们作为自己的唯一列表 table?即:
chkBrown
chkFiltered
chkRound
chkSize
chkSoft
chkSquare
chkStacked
chkYellow
您可以使用 string_split()
做您想做的事:
select s.value, count(*)
from survey su cross apply
string_split(su.responses, ';') s
group by s.value;
Here 是一个 db<>fiddle.
您可以这样做并不意味着您应该。您应该将响应存储在 单独的 table 中,每个响应一行。
如果这只是一个简单的一页,只有复选框的调查,一种方法是
// 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
但是……又一次。这仅在不需要更改且系统是静态的情况下才有用。这似乎是家庭作业,不是长期问题。但在这种情况下,长期情况是多对多 table,您可以将同一问题的多个记录作为单独的记录发布。这样,SQL搜索就很容易了
此处有效fiddle,您还可以在其中了解如何将复选框设置为从数字中检索到的值
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
}
}
我正在 table 中收集对在线调查表的回复,如下所示:
CREATE TABLE [Survey]
(
ID int IDENTITY(1,1) NOT NULL,
UserName varchar(50) NOT NULL,
Responses varchar(max) NOT NULL,
Taken datetime NOT NULL
)
当用户点击提交按钮时,一个进程会抓取所有被点击的复选框并将它们的名称连接成一个分隔字符串,并将其与其他字段一起填充到 table 中。基本相同:
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())
有没有一种方法可以轻松地遍历整个 table 的所有 "Responses",找到所有可能的值,然后 return 它们作为自己的唯一列表 table?即:
chkBrown
chkFiltered
chkRound
chkSize
chkSoft
chkSquare
chkStacked
chkYellow
您可以使用 string_split()
做您想做的事:
select s.value, count(*)
from survey su cross apply
string_split(su.responses, ';') s
group by s.value;
Here 是一个 db<>fiddle.
您可以这样做并不意味着您应该。您应该将响应存储在 单独的 table 中,每个响应一行。
如果这只是一个简单的一页,只有复选框的调查,一种方法是
// 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
但是……又一次。这仅在不需要更改且系统是静态的情况下才有用。这似乎是家庭作业,不是长期问题。但在这种情况下,长期情况是多对多 table,您可以将同一问题的多个记录作为单独的记录发布。这样,SQL搜索就很容易了
此处有效fiddle,您还可以在其中了解如何将复选框设置为从数字中检索到的值
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
}
}