Sql 将多个布尔列连接到单个varchar列

Sql 将多个布尔列连接到单个varchar列,sql,postgresql,Sql,Postgresql,我正在利用PostgreSQL将数据从一个表转换到另一个表,目前在布尔列方面遇到了一些挑战。我想将带有布尔值的表转换为一个分号分隔的varchar字段 下面是我正在执行的两个CREATETABLE语句 CREATE TABLE Color_Table ( "Id" VARCHAR(255), "IsRed" BOOL, "IsOrange" BOOL, "IsYellow" BOOL, "IsGreen" BOOL, "IsBlue" BOOL, "IsIndigo" BOOL, "IsViol

我正在利用PostgreSQL将数据从一个表转换到另一个表,目前在布尔列方面遇到了一些挑战。我想将带有布尔值的表转换为一个分号分隔的varchar字段

下面是我正在执行的两个CREATETABLE语句

CREATE TABLE Color_Table
(
"Id" VARCHAR(255),
"IsRed" BOOL,
"IsOrange" BOOL,
"IsYellow" BOOL,
"IsGreen" BOOL,
"IsBlue" BOOL,
"IsIndigo" BOOL,
"IsViolet" BOOL
)

CREATE TABLE Concatenated_Table
(
"Id" VARCHAR(255),
"Semicolon_Colors" VARCHAR(255)
)
下面是一个示例行,我正在将其插入到Color_表中。我的期望是将其转换为值:红色;绿色靛蓝;紫罗兰色

INSERT INTO Color_Table
(
"Id",
"IsRed",
"IsOrange",
"IsYellow",
"IsGreen",
"IsBlue",
"IsIndigo",
"IsViolet"
) 

VALUES
(
'12345_abcd_67890',
true,
false,
false,
true,
false,
true,
true
)
我试图通过声明来创建一个临时变量,并收到一条错误消息。下面是我尝试使用的脚本/方法

DECLARE TempVariable VARCHAR(255);
INSERT INTO Concatenated_Table
    (
        "Id",
        "Semicolon_Colors"
    )
SELECT
colors."Id",
BEGIN
    TempVariable = ''

    IF(colors."IsRed" = true)
    BEGIN
        CONCAT(TempVariable, 'Red; ')
    END

    IF(colors."IsOrange" = true)
    BEGIN
        CONCAT(TempVariable, 'Orange; ')
    END

    IF(colors."IsYellow" = true)
    BEGIN
        CONCAT(TempVariable, 'Yellow; ')
    END

    IF(colors."IsGreen" = true)
    BEGIN
        CONCAT(TempVariable, 'Green; ')
    END

    IF(colors."IsBlue" = true)
    BEGIN
        CONCAT(TempVariable, 'Blue; ')
    END

    IF(colors."IsIndigo" = true)
    BEGIN
        CONCAT(TempVariable, 'Indigo; ')
    END

    IF(colors."IsViolet" = true)
    BEGIN
        CONCAT(TempVariable, 'Violet; ')
    END
END
FROM Color_Table colors

对于如何做到这一点,我们非常感谢您的任何建议

我仍然认为表设计是一个坏主意,但是您应该能够将您的案例连接到一个单独的列中—类似这样的

更新:从mssql更改为Postgres语法:

SELECT
"Id",
CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(
  CASE "IsRed" WHEN true THEN 'Red; ' ELSE '' END,
  CASE "IsOrange" WHEN true THEN 'Red; ' ELSE '' END), 
  CASE "IsYellow" WHEN true THEN 'Yellow; ' ELSE '' END),
  CASE "IsGreen" WHEN true THEN 'Green; ' ELSE '' END),
  CASE "IsBlue" WHEN true THEN 'Blue; ' ELSE '' END),
  CASE "IsIndigo" WHEN true THEN 'Indigo; ' ELSE '' END),
  CASE "IsViolet" WHEN true THEN 'Violet; ' ELSE '' END)
  AS Semicolon_Colors
FROM color_table
另一种更简洁的语法(感谢@a_horse_和_no_name):


可以使用
concat_ws()
简化连接,因为这会处理分隔符
和将忽略空值,这意味着
大小写
表达式不需要显式的
else'
部分:

insert into Concatenated_Table ("Id", "Semicolon_Colors")
select "Id", 
       concat_ws('; ', 
          case when "IsRed" then 'Red' end, 
          case when "IsOrange" then 'Red' end, 
          case when "IsYellow" then 'Yellow' end ,
          case when "IsGreen" then 'Green' end,
          case when "IsBlue" then 'Blue' end,
          case when "IsIndigo" then 'Indigo' end,
          case when "IsViolet" then 'Violet' end) 
from Color_Table;
如果您确实需要保留各个颜色列,我宁愿使用上面的
select
语句创建一个视图,而不是将数据复制到一个新表中。concat和case语句非常便宜。由于性能原因,无需复制数据



不相关,但是:您应该真正尝试避免引用标识符
“IsRead”
,因为它们带来的麻烦远远超过了它们的价值。(但如果使用它们,则应保持一致,表名不使用带引号的标识符,但列使用带引号的标识符)。

但问题是postgresql或其他标记……?理想情况下,postgresql可以在MS SQL Server中完成,但如有必要。希望在PostgreSQL中进行处理,以避免将其与现有数据库分离。如果希望在单个列中存储多个值,这通常不是一个好主意。如何查询所有蓝色和黄色等行。。。?在任何情况下,更传统的方法可能是一个整数列,您可以在其中应用位比较来确定哪些颜色是开的或关的。@scaisEdge已修改,谢谢您的建议。更好的设计是使用带有“Id”和“Color”的代理表字段,该字段将包含给定ID的所有有效颜色。以后可以很容易地查询并允许使用其他颜色。SQL(和Postgres)使用
|
连接字符串,而不是
+
,并且在读取时可以将大小写简化为
大小写,然后选择“红色;”else''end
@a_horse_,没有名字-谢谢-只是在为Postgre更新-我不知道| |操作符-这会为Postgres清理Nicley。没有必要嵌套
concat()
调用。您可以使用
concat(case..end,case..end,case..end,…)
谢谢您发布这个@snow_FFFFFF,我非常感谢您在这件事上的帮助。我知道这是次优的,但本质上这是故意的,因为源表有多个布尔列,而目标表是集成到另一个数据库的阶段,架构师不希望存储多个布尔属性。感谢您的回复!我试过这个和@snow_FFFFFF,两种方法都有效。我也很感谢你关于:惯例,这是我第一次进入博士后。我的用例是显示源表和目标表,以便在最终推入另一个数据库之前修改目标表。这有点做作,尽管我对源代码和目标代码之间所需的翻译方法感到更舒服。
insert into Concatenated_Table ("Id", "Semicolon_Colors")
select "Id", 
       concat_ws('; ', 
          case when "IsRed" then 'Red' end, 
          case when "IsOrange" then 'Red' end, 
          case when "IsYellow" then 'Yellow' end ,
          case when "IsGreen" then 'Green' end,
          case when "IsBlue" then 'Blue' end,
          case when "IsIndigo" then 'Indigo' end,
          case when "IsViolet" then 'Violet' end) 
from Color_Table;