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 转换为 DATENVARCHAR 这里 -

...
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_FLAGDATE_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 子句,但上述方法可能有效。