我正在利用PostgreSQL将数据从一个表转换为另一个表,目前我正在使用布尔列遇到一些挑战。我想将一个带有布尔值的表转换为一个以分号分隔的varchar字段。
以下是我正在执行的两个CREATE TABLE语句。
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_Table的示例行。我的期望是将其转化为价值:红色;绿色;靛青;紫;
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
对于如何做到这一点,我们非常感谢任何建议!
答案 0 :(得分:1)
我仍然认为表格设计是一个坏主意,但你应该能够将你的案例连接成一个列 - 就像这样
更新:从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_with_no_name):
SELECT
"Id",
CASE WHEN "IsRed" THEN 'Red; ' ELSE '' END ||
CASE WHEN "IsOrange" THEN 'Red; ' ELSE '' END ||
CASE WHEN "IsYellow" THEN 'Yellow; ' ELSE '' END ||
CASE WHEN "IsGreen" THEN 'Green; ' ELSE '' END ||
CASE WHEN "IsBlue" THEN 'Blue; ' ELSE '' END ||
CASE WHEN "IsIndigo" THEN 'Indigo; ' ELSE '' END ||
CASE WHEN "IsViolet" THEN 'Violet; ' ELSE '' END
AS Semicolon_Colors
FROM color_table
答案 1 :(得分:1)
可以使用concat_ws()
简化串联,因为这会处理分隔符;
并忽略空值,这意味着case
表达式不需要显式{ {1}}部分:
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;
语句创建一个视图,而不是将数据复制到一个新表中。 concat和case语句非常便宜。出于性能原因,无需复制数据。
无关,但是:你应该尽量避免使用带引号的标识符select
它们比它们的价值要大得多。 (但是如果你使用它们,那么你应该保持一致,你的表名不要使用带引号的标识符,但是你的列也可以。)