2

したがって、データの列があります。前の例である体温を使用すると、レコードが拒否されないように varchar として保存されますが、数値データが含まれています。

私にデータを送ってきた人々は完璧とは言えないシステムを使用しているため、間違ったデータがいくつかあります。私がする必要があるのは、特定の値より上または下の有効な値を見つけるための SQL クエリを作成することです。

たとえば、104 を超えるすべての温度は、極端なケースまたはエラーを示しているはずです。

私は試した:

select count(1), result_num from VITALS where test_cd is 'TEMP' and cast(result_num as integer) > 104 group by result_num;

これにより無効な数値エラーが返されたため、一部の行に整数に変換できない文字があり、負の値 (数値の前に「-」) を持つレコードと「NULL」と表示されたレコードが見つかったので、修正しました読む私のクエリ:

select count(1), result_num from VITALS where test_cd is 'TEMP' **and result_num not like '%-%' and result_num not like '%NULL%'** and cast(result_num as integer) > 104 group by result_num;

...それでも無効な数値エラーが返されました。RESULT_NUM フィールドのデータを 3 回チェックしましたが、これらが唯一の文字応答です。

他のすべての応答は、正当な一時であるかどうかにかかわらず、小数点以外の文字を含まない数値です。

「好きではない」ステートメントを括弧などでリンクする必要がありますか?

これはおそらく単純な答えですが、それは私を夢中にさせています.

4

3 に答える 3

1

これは私にとってはうまくいきました。これは基本的に、@Alex がサブクエリについて行った提案です。ソースデータでうまくいくことを願っています:

SELECT count(*), result_num
FROM
(
  SELECT
  test_cd,
  CASE WHEN REGEXP_LIKE(result_num,'^-?[0-9]*\.?[0-9]*$')
    THEN result_num - 0
    ELSE NULL
  END result_num
  FROM vitals
) 
WHERE test_cd='TEMP'
  AND result_num > 104
GROUP BY result_num;

別の別のアイデア: Oracle 11g を使用していて、テーブル構造の変更を提案/作成できる場合は、サニタイズされたデータを計算するテーブルに仮想列 (つまり、計算列) を追加するというアイデアが気に入るかもしれません。数値。動作はビューに似ていますが、仮想列を使用することによる 2 つの大きな利点: (1) 追加のオブジェクトがなく、1 つのオブジェクト、つまりvitalsテーブルである、(2) 仮想列にインデックスを付けることができる (論理的には関数インデックス)。

11g を使用していない場合、または仮想列があまりにも錬金術のように聞こえる場合は、別の方法として、単純な古い列を作成してサニタイズされた値を保持し、トリガーに挿入/更新時にその値を計算させることもできます。

于 2014-06-19T06:38:30.150 に答える
0

EDIT : Oracle 10g 以降のバージョンを使用している場合は、正規表現を使用して、result_num 内の数字のみを検索できます。小数と負の数は除外されるため、次のように 0 ~ 9 の文字を探すだけです。

select result_num , count(1) as cnt_result_num
from VITALS 
where test_cd = 'TEMP' 
and result_num IS NOT NULL
and regexp_like(result_num, '^[0-9]*$')
and cast(result_num as integer) > 104 
group by result_num;

SQL Fiddle

参考

『Oracle Database SQLリファレンス』の REGEXP_LIKE

于 2014-06-18T17:02:03.053 に答える