小数点以下の桁数が0(小数点なし)から6(最大)の範囲の浮動小数点数でいっぱいの列Xがあります。小数点以下6桁を超えるフロートがないことを期待できます。それを踏まえて、小数点以下の桁数がわかるように新しい列を作成するにはどうすればよいですか?
CASTを使用してfloatを文字列に変換し、文字列を解析して小数点以下の文字列の長さをカウントすることを提案するスレッドをいくつか見ました。これが最善の方法ですか?
小数点以下の桁数が0(小数点なし)から6(最大)の範囲の浮動小数点数でいっぱいの列Xがあります。小数点以下6桁を超えるフロートがないことを期待できます。それを踏まえて、小数点以下の桁数がわかるように新しい列を作成するにはどうすればよいですか?
CASTを使用してfloatを文字列に変換し、文字列を解析して小数点以下の文字列の長さをカウントすることを提案するスレッドをいくつか見ました。これが最善の方法ですか?
次のようなものを使用できます。
declare @v sql_variant
set @v=0.1242311
select SQL_VARIANT_PROPERTY(@v, 'Scale') as Scale
これはを返し7
ます。
上記のクエリを列で機能させようとしましたがfloat
、期待どおりに機能しませんでした。ここに表示されているように、列でのみ機能しsql_variant
ます:http ://sqlfiddle.com/#!6/5c62c/2
それで、私は別の方法を見つけて、この答えに基づいて構築しました、私はこれを得ました:
SELECT value,
LEN(
CAST(
CAST(
REVERSE(
CONVERT(VARCHAR(50), value, 128)
) AS float
) AS bigint
)
) as Decimals
FROM Numbers
これをテストするためのSQLフィドルは次のとおりです。http://sqlfiddle.com/# !6 / 23d4f / 29
そのちょっとした癖を説明するために、float値に小数部がない場合を処理する修正バージョンを次に示します。
SELECT value,
Decimals = CASE Charindex('.', value)
WHEN 0 THEN 0
ELSE
Len (
Cast(
Cast(
Reverse(CONVERT(VARCHAR(50), value, 128)) AS FLOAT
) AS BIGINT
)
)
END
FROM numbers
付随するSQLフィドルは次のとおりです。http://sqlfiddle.com/#!6 / 10d54 / 11
このスレッドもCASTを使用していますが、答えは興味深いと思いました。
http://www.sqlservercentral.com/Forums/Topic314390-8-1.aspx
DECLARE @Places INT
SELECT TOP 1000000 @Places = FLOOR(LOG10(REVERSE(ABS(SomeNumber)+1)))+1
FROM dbo.BigTest
およびORACLEの場合:
SELECT FLOOR(LOG(10,REVERSE(CAST(ABS(.56544)+1 as varchar(50))))) + 1 from DUAL
フロートは実数を表しているだけです。実数の小数点以下の桁数には意味がありません。特に、実数3は小数点以下6桁、3.000000を持つことができます。これは、すべての小数点以下の桁数がゼロであるということだけです。
小数点以下の右端のゼロ値を表示していない表示変換がある可能性があります。
また、小数点以下6桁までの理由は、7桁目が不正確であるため、表示変換が小数点以下7桁の値にコミットされないことにも注意してください。
また、floatはバイナリで格納され、実際にはバイナリポイントの右側にバイナリの場所があることに注意してください。10進数の表示は、浮動小数点ストレージ内の2進数の有理数の近似値であり、実数の近似値です。
つまり、要点は、float値の小数点以下の桁数が実際にはわからないということです。文字列への変換を行う場合(たとえば、CASTを使用して)、小数点以下の桁数を数えることができます。それは本当にあなたがやろうとしていることのための最良のアプローチでしょう。
以前に回答しましたが、コメントから少しわかりにくいことがわかります。時間が経つにつれて、私はこれを表現するためのより良い方法を見つけました。
円周率を次のように考えます
(a) 3.141592653590
これは、円周率を小数点以下11桁として表示します。ただし、これは円周率として小数点以下12桁に丸められ、14桁になります。
(b) 3.1415926535897932
コンピューターまたはデータベースは、値をバイナリーで保管します。単精度浮動小数点の場合、piは次のように格納されます。
(c) 3.141592739105224609375
これは、(a)で丸めたように、実際には単精度で格納できる最も近い値に切り上げられます。単精度で格納できる次の最小数は
(d) 3.141592502593994140625
したがって、小数点以下の桁数を数えようとすると、小数点以下の桁数を見つけようとします。その後、残りの小数点以下はすべてゼロになります。ただし、数値を格納するために数値を四捨五入する必要がある場合があるため、正しい値を表すものではありません。
数値は、数値を入力するときに10進数から2進数に変換したり、値を表示するときに2進数から10進数に変換したりするなど、数学的な操作が行われるときに丸め誤差ももたらします。
データベース内の数値は、限られた量のストレージに格納するために四捨五入されているため、小数点以下の桁数を確実に見つけることはできません。実際の値の差、またはデータベース内の正確な2進値でさえ、10進数で表すために丸められます。四捨五入から欠落している小数点以下の桁が常に増える可能性があるため、ゼロの後にゼロ以外の桁がなくなる時期はわかりません。
Oracleのソリューションですが、あなたはその考えを理解しました。trunc()は、Oracleの小数部を削除します。
select *
from your_table
where (your_field*1000000 - trunc(your_field*1000000)) <> 0;
クエリのアイデア:1 000 000を掛けた後、小数は残りますか。
私が見つけた別の方法は
SELECT 1.110000、LEN(PARSENAME(Cast(1.110000 as float)、1))AS Count_AFTER_DECIMAL
KshitijManvelikarの答えにバグがあることに気づきました。小数点以下の桁数がない場合は、0を返す代わりに、数値の合計文字数を返します。
だからそれを改善する:
Case When (SomeNumber = Cast(SomeNumber As Integer)) Then 0 Else LEN(PARSENAME(Cast(SomeNumber as float),1)) End
これが別のOracleの例です。Oracle以外のユーザーが私に向かって叫んだり、反対票を投じたりする前に、常に警告しているので、SUBSTRINGとINSTRINGはANSI SQL標準関数であり、任意のSQLで使用できます。デュアルテーブルは、他のテーブルと交換したり、作成したりできます。デュアルテーブルコードをhttp://blog.sqlauthority.com/2010/07/20/sql-server-select-from-dual-dual-equivalent/からコピーしたSQLSERVERブログへのリンクは次のとおりです。
CREATE TABLE DUAL
(
DUMMY VARCHAR(1)
)
GO
INSERT INTO DUAL (DUMMY)
VALUES ('X')
GO
ドットまたは小数点以下の長さは、このクエリによって返されます。strは、必要に応じてto_number(str)に変換できます。ドットの小数点以下の桁数の前の文字列の長さを取得することもできます-コードをLENGTH(SUBSTR(str、1、dot_pos))-1に変更し、INSTR部分の+1を削除します。
SELECT str, LENGTH(SUBSTR(str, dot_pos)) str_length_after_dot FROM
(
SELECT '000.000789' as str
, INSTR('000.000789', '.')+1 dot_pos
FROM dual
)
/
SQL>
STR STR_LENGTH_AFTER_DOT
----------------------------------
000.000789 6
キャストなどについての回答と例はすでにあります...
この質問は通常のSQLについて尋ねますが、SQLiteのソリューションが必要でした。SQLiteにはlog10関数も逆文字列関数も組み込まれていないため、ここでの回答のほとんどは機能しません。私の解決策はArtの答えに似ており、実際のところ、ファンが質問の本文で説明しているものに似ています。これは、浮動小数点値(SQLiteでは「REAL」値)をテキストに変換し、小数点以下の文字をカウントすることで機能します。
「Table」という名前のテーブルの「Column」という名前の列の場合、次のクエリは各行の小数点以下の桁数を生成します。
select
length(
substr(
cast(Column as text),
instr(cast(Column as text), '.')+1
)
) as "Column-precision" from "Table";
コードは列をテキストとしてキャストし、テキスト内のピリオド(.
)のインデックスを取得し、そのポイントからテキストの最後まで部分文字列をフェッチします。次に、結果の長さを計算します。
limit 100
テーブル全体で実行したくない場合は、覚えておいてください。
これは完璧な解決策ではありません。たとえば、「10.0」は小数点以下1桁と見なされますが、これは0だけですが、実際にはこれが必要だったので、気になりませんでした。
うまくいけば、これは誰かに役立つでしょう:)