PIVOT table 正在将所有列转换为 DATE
PIVOT table is converting all columns to DATE
为什么我创建的视图使用 FIRM_PANEL 和 FIRM_DATE 作为 DATE 而不是我期望的 NVARCHAR 和 DATE?
SELECT DISTINCT piv3.CASE_NUMBER, FIRM_PANEL, FIRM_DATE
FROM
(
SELECT DISTINCT piv2.CASE_NUMBER, piv2.DETAIL_CODE,
CASE piv2.DATA_FLAGS
WHEN 'TEXT_FLAG' THEN CONVERT(NVARCHAR, TEXT_VALUE)
WHEN 'DATE_FLAG' THEN CONVERT(DATE, DATE_VALUE)
END AS 'VALUE'
FROM
(
SELECT DISTINCT CASE_NUMBER, DETAIL_CODE, piv.DATA_FLAGS, TEXT_VALUE, CONVERT(DATE, DATE_VALUE) AS DATE_VALUE
FROM table
UNPIVOT
(
YES_OR_NO
FOR DATA_FLAGS IN (DATE_FLAG, TEXT_FLAG)
) piv
) piv2
) as sourcetable
PIVOT
(
MAX(VALUE)
FOR DETAIL_CODE IN (FIRM_PANEL,
FIRM_DATE )
) AS piv3
让我解释一下每个嵌套 pivot/select。第一个 SELECT 让您了解数据是如何存储的。我需要一种方法来将 1 CASE_NUMBER 和 DETAIL_CODEs 显示为唯一列。
SELECT DISTINCT CASE_NUMBER, DETAIL_CODE, piv.DATA_FLAGS, TEXT_VALUE,
CONVERT(DATE, DATE_VALUE) AS DATE_VALUE
FROM table
然后我需要将 DATE_VALUE 和 TEXT_VALUE 合并到一个名为 VALUE 的列中,因此我的 UNPIVOT。
SELECT DISTINCT piv2.CASE_NUMBER, piv2.DETAIL_CODE,
CASE piv2.DATA_FLAGS
WHEN 'TEXT_FLAG' THEN CONVERT(NVARCHAR, TEXT_VALUE)
WHEN 'DATE_FLAG' THEN CONVERT(NVARCHAR, DATE_VALUE)
END AS 'VALUE'
FROM
(
SELECT DISTINCT CASE_NUMBER, DETAIL_CODE, piv.DATA_FLAGS, TEXT_VALUE, CONVERT(DATE, DATE_VALUE) AS DATE_VALUE
FROM table
UNPIVOT
(
YES_OR_NO
FOR DATA_FLAGS IN (DATE_FLAG, TEXT_FLAG)
) piv
) piv2
然后我的最终 SQL(顶部)终于再次 PIVOT 并删除空值并解释如果该列是文本字段则使用 NVARCHAR,如果日期使用 DATE。
但是,我可以从视图中 SELECT 而没有错误的唯一方法是同时生成 NVARCHAR 否则我将收到 "Conversion failed when converting date and/or time from character string" 因为这两列都是 DATE 字段,而它们不应该是.但是我不明白为什么视图是用两个 DATE 列创建的。我当前的解决方法是设置为字符串,并在从视图中选择时仅进行转换。
抱歉啰嗦。
我不太明白你使用数据透视表的原因,但问题似乎是你试图将同一列 VALUE
转换为 DATE
和 NVARCHAR
这里 -
...
CASE piv2.DATA_FLAGS
WHEN 'TEXT_FLAG' THEN CONVERT(NVARCHAR, TEXT_VALUE)
WHEN 'DATE_FLAG' THEN CONVERT(DATE, DATE_VALUE)
END AS 'VALUE'
...
您无法控制 SQL 服务器何时执行 CONVERT
操作,它可能会在检查 DATA_FLAGS
之前执行此操作。如果您尝试将 CONVERT
移到第一个 select -
之外,您的查询应该有效
SELECT DISTINCT piv3.CASE_NUMBER, CONVERT(NVARCHAR, FIRM_PANEL), CONVERT(DATE, FIRM_DATE)
FROM
(
SELECT DISTINCT piv2.CASE_NUMBER, piv2.DETAIL_CODE,
CASE piv2.DATA_FLAGS
WHEN 'TEXT_FLAG' THEN TEXT_VALUE
WHEN 'DATE_FLAG' THEN DATE_VALUE
END AS 'VALUE'
...
如果您愿意不使用数据透视表,这里有一个简单的替代方法来获得相同的结果 -
SELECT CASE_NUMBER
, MAX(CASE WHEN DATA_FLAGS = 'TEXT_FLAG' THEN TEXT_VALUE END) FIRM_DATE
, MAX(CASE WHEN DATA_FLAGS = 'DATE_FLAG' THEN CONVERT(DATE, DATE_VALUE) END) FIRM_PANEL
FROM #in
GROUP BY CASE_NUMBER
这给出了与您正在寻找的结果相同的结果,其中的列具有预期的数据类型。请注意,它假设每个 CASE_NUMBER
.
您只有一条记录 TEXT_FLAG
和 DATE_FLAG
我认为 and-d 走在正确的道路上。您绝对应该尝试案例聚合。
SELECT CASE_NUMBER,
MAX( CASE WHEN DETAIL_CODE = 'FIRM_PANEL' THEN TEXT_VALUE END) AS FIRM_PANEL,
MAX( CASE WHEN DETAIL_CODE = 'FIRM_DATE' THEN CONVERT(DATE, DATE_VALUE) END) AS FIRM_DATE
FROM table
GROUP BY CASE_NUMBER
如果需要,您可以在 case 表达式中添加更多的 where 子句,但上述方法可能有效。
为什么我创建的视图使用 FIRM_PANEL 和 FIRM_DATE 作为 DATE 而不是我期望的 NVARCHAR 和 DATE?
SELECT DISTINCT piv3.CASE_NUMBER, FIRM_PANEL, FIRM_DATE
FROM
(
SELECT DISTINCT piv2.CASE_NUMBER, piv2.DETAIL_CODE,
CASE piv2.DATA_FLAGS
WHEN 'TEXT_FLAG' THEN CONVERT(NVARCHAR, TEXT_VALUE)
WHEN 'DATE_FLAG' THEN CONVERT(DATE, DATE_VALUE)
END AS 'VALUE'
FROM
(
SELECT DISTINCT CASE_NUMBER, DETAIL_CODE, piv.DATA_FLAGS, TEXT_VALUE, CONVERT(DATE, DATE_VALUE) AS DATE_VALUE
FROM table
UNPIVOT
(
YES_OR_NO
FOR DATA_FLAGS IN (DATE_FLAG, TEXT_FLAG)
) piv
) piv2
) as sourcetable
PIVOT
(
MAX(VALUE)
FOR DETAIL_CODE IN (FIRM_PANEL,
FIRM_DATE )
) AS piv3
让我解释一下每个嵌套 pivot/select。第一个 SELECT 让您了解数据是如何存储的。我需要一种方法来将 1 CASE_NUMBER 和 DETAIL_CODEs 显示为唯一列。
SELECT DISTINCT CASE_NUMBER, DETAIL_CODE, piv.DATA_FLAGS, TEXT_VALUE,
CONVERT(DATE, DATE_VALUE) AS DATE_VALUE
FROM table
然后我需要将 DATE_VALUE 和 TEXT_VALUE 合并到一个名为 VALUE 的列中,因此我的 UNPIVOT。
SELECT DISTINCT piv2.CASE_NUMBER, piv2.DETAIL_CODE,
CASE piv2.DATA_FLAGS
WHEN 'TEXT_FLAG' THEN CONVERT(NVARCHAR, TEXT_VALUE)
WHEN 'DATE_FLAG' THEN CONVERT(NVARCHAR, DATE_VALUE)
END AS 'VALUE'
FROM
(
SELECT DISTINCT CASE_NUMBER, DETAIL_CODE, piv.DATA_FLAGS, TEXT_VALUE, CONVERT(DATE, DATE_VALUE) AS DATE_VALUE
FROM table
UNPIVOT
(
YES_OR_NO
FOR DATA_FLAGS IN (DATE_FLAG, TEXT_FLAG)
) piv
) piv2
然后我的最终 SQL(顶部)终于再次 PIVOT 并删除空值并解释如果该列是文本字段则使用 NVARCHAR,如果日期使用 DATE。
但是,我可以从视图中 SELECT 而没有错误的唯一方法是同时生成 NVARCHAR 否则我将收到 "Conversion failed when converting date and/or time from character string" 因为这两列都是 DATE 字段,而它们不应该是.但是我不明白为什么视图是用两个 DATE 列创建的。我当前的解决方法是设置为字符串,并在从视图中选择时仅进行转换。
抱歉啰嗦。
我不太明白你使用数据透视表的原因,但问题似乎是你试图将同一列 VALUE
转换为 DATE
和 NVARCHAR
这里 -
...
CASE piv2.DATA_FLAGS
WHEN 'TEXT_FLAG' THEN CONVERT(NVARCHAR, TEXT_VALUE)
WHEN 'DATE_FLAG' THEN CONVERT(DATE, DATE_VALUE)
END AS 'VALUE'
...
您无法控制 SQL 服务器何时执行 CONVERT
操作,它可能会在检查 DATA_FLAGS
之前执行此操作。如果您尝试将 CONVERT
移到第一个 select -
SELECT DISTINCT piv3.CASE_NUMBER, CONVERT(NVARCHAR, FIRM_PANEL), CONVERT(DATE, FIRM_DATE)
FROM
(
SELECT DISTINCT piv2.CASE_NUMBER, piv2.DETAIL_CODE,
CASE piv2.DATA_FLAGS
WHEN 'TEXT_FLAG' THEN TEXT_VALUE
WHEN 'DATE_FLAG' THEN DATE_VALUE
END AS 'VALUE'
...
如果您愿意不使用数据透视表,这里有一个简单的替代方法来获得相同的结果 -
SELECT CASE_NUMBER
, MAX(CASE WHEN DATA_FLAGS = 'TEXT_FLAG' THEN TEXT_VALUE END) FIRM_DATE
, MAX(CASE WHEN DATA_FLAGS = 'DATE_FLAG' THEN CONVERT(DATE, DATE_VALUE) END) FIRM_PANEL
FROM #in
GROUP BY CASE_NUMBER
这给出了与您正在寻找的结果相同的结果,其中的列具有预期的数据类型。请注意,它假设每个 CASE_NUMBER
.
TEXT_FLAG
和 DATE_FLAG
我认为 and-d 走在正确的道路上。您绝对应该尝试案例聚合。
SELECT CASE_NUMBER,
MAX( CASE WHEN DETAIL_CODE = 'FIRM_PANEL' THEN TEXT_VALUE END) AS FIRM_PANEL,
MAX( CASE WHEN DETAIL_CODE = 'FIRM_DATE' THEN CONVERT(DATE, DATE_VALUE) END) AS FIRM_DATE
FROM table
GROUP BY CASE_NUMBER
如果需要,您可以在 case 表达式中添加更多的 where 子句,但上述方法可能有效。