3

我有一张桌子Prices

ID Price_1 Price_2 Price_3

P1 10      11      12
P2 13      14      15
P3 aa      16      bb
P4 19      cc      20

从上面可以看出,列中的一些值Price_1可能Price_2不是Price_3数字。

我想要的是首先找到所有这些non-numeric values然后给出一个摘要(concatenate一个id的所有非数字值和列)

所以对于上面的例子,我想要的是

ID   Bad_Columns      Bad_Values
P3   Price_1,Price_3  aa,bb
P4   Price_2          cc

我应该如何编写这个查询?

4

3 回答 3

2

你可以这样做:

WITH CTE AS
(   SELECT  ID, Value, ColumnName
    FROM    Prices
            UNPIVOT
            (   Value
                FOR ColumnName IN ([Price_1], [Price_2], [Price_3])
            ) upvt
    WHERE   ISNUMERIC(Value) = 0
)
SELECT  ID,
        BadColumns = STUFF((SELECT  ', ' + ColumnName 
                            FROM    CTE
                            WHERE   CTE.ID = t.ID
                            FOR XML PATH(''), TYPE
                        ).value('.', 'NVARCHAR(MAX)'), 1, 2, ''),
        BadValues = STUFF(( SELECT  ', ' + Value 
                            FROM    CTE
                            WHERE   CTE.ID = t.ID
                            FOR XML PATH(''), TYPE
                        ).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
FROM    (SELECT DISTINCT ID FROM CTE) t

第一部分 UNPIVOT 将您的查询作为行获取列,然后第二部分将“坏”行连接成一列。

SQL Fiddle 示例

于 2013-03-04T15:56:35.770 回答
0

我会建议:

select p.*
from ((select id, price_1 as price, 'price_1' as col) union all
      (select id, price_2 as price, 'price_2' as col) union all
      (select id, price_3 as price, 'price_3' as col)
     ) p
where is_numeric(price) = 0 and price is not null

如果您真的希望它们采用您拥有的格式,只需执行以下操作:

select id,
       stuff((case when isnumeric(price_1) = 1 then ',Price_1' else '' end) +
             (case when isnumeric(price_2) = 1 then ',Price_2' else '' end) +
             (case when isnumeric(price_3) = 1 then ',Price_3' else '' end)
            ), 1, 1, '') as Bad_Columns,
       stuff((case when isnumeric(price_1) = 1 then ','+Price_1 else '' end) +
             (case when isnumeric(price_2) = 1 then ','+Price_2 else '' end) +
             (case when isnumeric(price_3) = 1 then ','+Price_3 else '' end)
            ), 1, 1, '') as Bad_Values
from p
where isnumeric(price_1) = 0 or isnumeric(price_2)= 0 or isnumeric(price_3) = 0

我不使用的原因unpivot是因为它假设列类型是兼容的。如果要将其扩展到更多列,请使用 Excel 生成代码。

于 2013-03-04T15:59:34.157 回答
0

您可以使用以下内容对数据进行反透视,然后使用以下方法连接值FOR XML PATH

;with cte as
(
  select id, col, data
  from
  (
    select t.id,
      c.col,
      case c.col
        when 'Price_1' then Price_1
        when 'Price_2' then Price_2
        when 'Price_3' then Price_3
      end as data
    from yourtable t
    cross join
    (
      select 'Price_1' as col
      union all select 'Price_2'
      union all select 'Price_3'
    ) c
  ) src
  where isnumeric(data) = 0
)
select distinct c1.id,
  stuff((select ', ' + col
         from cte c2
         where c1.id = c2.id
         FOR XML PATH (''))
          , 1, 1, '')  AS Bad_columns,
  stuff((select ', ' + data
         from cte c2
         where c1.id = c2.id
         FOR XML PATH (''))
          , 1, 1, '')  AS Bad_Values
from cte c1

请参阅SQL Fiddle with Demo

这也可以使用以下unpivot函数编写:

;with cte as
(
  select id, col, data
  from yourtable
  unpivot
  (
    data
    for col in ([Price_1], [Price_2], [Price_3])
  ) unpiv
  where isnumeric(data) = 0
)
select distinct c1.id,
  stuff((select ', ' + col
         from cte c2
         where c1.id = c2.id
         FOR XML PATH (''))
          , 1, 1, '')  AS Bad_columns,
  stuff((select ', ' + data
         from cte c2
         where c1.id = c2.id
         FOR XML PATH (''))
          , 1, 1, '')  AS Bad_Values
from cte c1

请参阅SQL Fiddle with Demo。结果是:

| ID |       BAD_COLUMNS | BAD_VALUES |
---------------------------------------
| P3 |  Price_1, Price_3 |     aa, bb |
| P4 |           Price_2 |         cc |
于 2013-03-04T15:57:35.757 回答