3

テーブルが1つあります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_2Price_3

私が欲しいのは、最初にそれらすべてを見つけてnon-numeric valuesから要約を与えることです(concatenate1つの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して列を行として取得し、2番目の部分は「不良」行を1つの列に連結します。

SQLフィドルの例

于 2013-03-04T15:56:35.770 に答える
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 FiddlewithDemoを参照してください。

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 FiddlewithDemoを参照してください。結果は次のとおりです。

| ID |       BAD_COLUMNS | BAD_VALUES |
---------------------------------------
| P3 |  Price_1, Price_3 |     aa, bb |
| P4 |           Price_2 |         cc |
于 2013-03-04T15:57:35.757 に答える
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 に答える