PIVOT表将所有列转换为DATE

时间:2018-01-12 20:56:34

标签: sql-server pivot unpivot

为什么我的视图是使用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

enter image description here

让我解释每个嵌套的pivot / select。第一个SELECT让您了解数据如何存储原始数据。我需要一种方法将1个CASE_NUMBER和DETAIL_CODE显示为唯一列。

SELECT DISTINCT CASE_NUMBER, DETAIL_CODE, piv.DATA_FLAGS, TEXT_VALUE, 
CONVERT(DATE, DATE_VALUE) AS DATE_VALUE
    FROM table

enter image description here

然后我需要将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 

enter image description here

然后我的最终SQL(顶部)最后再次PIVOTs并删除空值并解释如果列是文本字段然后使用NVARCHAR并且如果日期使用DATE。

enter image description here

然而,我可以从视图中选择而没有错误的唯一方法是同时生成NVARCHAR,否则我会收到“转换从字符串转换日期和/或时间时失败”,因为这两列都是DATE字段不会。但是我不明白为什么使用两个DATE列创建视图。我目前的解决方法是设置为字符串,并在从视图中进行选择时进行转换。

对于这句话感到抱歉。

2 个答案:

答案 0 :(得分:1)

我认为an-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子句,但上述内容可能有效。

答案 1 :(得分:0)

我不太了解您使用枢轴的原因,但问题似乎是您尝试将同一列render() { let recipeArray = [ "jamaican rum", "fresh lime juice", "simple syrup", "Angostura Aromatic Bitters" ]; let items = recipeArray.map((item, index) => <li key={index}>{item}</li>); return ( <div> <ul>{items}</ul> </div> ); } 与同一列VALUE和{{1}这里 -

DATE

您无法控制SQL Server何时执行NVARCHAR操作,并且可能在检查... CASE piv2.DATA_FLAGS WHEN 'TEXT_FLAG' THEN CONVERT(NVARCHAR, TEXT_VALUE) WHEN 'DATE_FLAG' THEN CONVERT(DATE, DATE_VALUE) END AS 'VALUE' ... 之前执行此操作。如果您尝试将CONVERT外部移动到第一个选择 -

,则您的查询应该有效
DATA_FLAGS

如果你愿意不使用枢轴,这里有一个简单的替代方案来获得相同的结果 -

CONVERT

这与您在预期数据类型中的列所寻找的结果相同。请注意,它假设您每个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 TEXT_FLAG