1

日付フィールドに基づいて選択するクエリがあります。問題は、この日付フィールドが null の場合があるため、'and not null' を使用して null をチェックするだけでは機能しないことです。

これが私が開発したものです:

SELECT DISTINCT WS_ALL_OBJ.[Owner ID], Users.CHARGE_UNIT, WS_ALL_OBJ.[Owner Name]
FROM WS_ALL_OBJ LEFT JOIN Users ON WS_ALL_OBJ.[Owner ID] = Users.CNAME
WHERE 
    (IIF(IsNull(WS_ALL_OBJ.[Last Modified]), DateValue('2050-12-01'), DateValue(Left(WS_ALL_OBJ.[Last Modified], 10))) < #2012-11-26#
   And 
    (Users.CHARGE_UNIT <> 'CQ'))
GROUP BY WS_ALL_OBJ.[Owner ID], Users.CHARGE_UNIT, WS_ALL_OBJ.[Owner Name];

このクエリを実行すると、「条件式のデータ型が一致しません」というエラー メッセージがスローされます。

このコード行に絞り込みました。これDateValue(Left(WS_ALL_OBJ.[Last Modified], 10))を置き換えると、DateValue('2011-11-26')問題なく動作するからです。

最初は、フィールドにnull値があるためだと思ったので、Last Modifiedこれを思いつきました-(IIF(IsNull(WS_ALL_OBJ.[Last Modified]), DateValue('2050-12-01'), DateValue(Left(WS_ALL_OBJ.[Last Modified], 10))) < #2012-11-26#

それはnullの問題を解決するべきではありませんか?

もう 1 つの可能性は、元の文字列Left()の形式が正しくないことです。私がこれを考える理由は、これ - DateValue('2011-11026')- (間違った形式) もデータ型の不一致例外を通過するからです。

ただし、これはすべてのデータがどのように見えるかです。

2008-01-18 13:10:54 CST

「テキスト」フィールドとして保存され、リンクされた csv ファイルから取得されます。Left()関数は最初の 10 文字を取得し、DateValue()

私は途方に暮れており、助けに感謝します。

更新:私も試してみcdate(Left(WS_ALL_OBJ.[Last Modified], 10))ましたが、同じエラーが発生しました。`(IsNull(WS_ALL_OBJ.[Last Modified]) または WS_ALL_OBJ.[Last Modified] = '') で空の文字列をチェックするように変更しました。

WS_ALL_OBJ.[Last Modified] = ''などが存在しないことを確認するためだけに、いくつかのクエリを実行することになりましWS_ALL_OBJ.[Last Modified] = ' 'た。それらはすべてゼロの結果を返しました。

以下で提案されているクエリ構造も試しましたが、役に立ちませんでした。

4

2 に答える 2

1

NullWS_ALL_OBJである行を除外するサブクエリを検討してください。[Last Modified]そうすれば、Null を日付/時刻値にキャストしようとしたときに発生するエラーを回避できます。

SELECT
    w.[Owner ID], u.CHARGE_UNIT, w.[Owner Name]
FROM
    (
        SELECT [Owner ID], [Owner Name], [Last Modified]
        FROM WS_ALL_OBJ
        WHERE [Last Modified] Is Not Null
    ) AS w
    LEFT JOIN Users AS u
    ON w.[Owner ID] = u.CNAME
WHERE 
        DateValue(Left(w.[Last Modified], 10)) < #2012-11-26#
    AND u.CHARGE_UNIT <> 'CQ'
GROUP BY w.[Owner ID], u.CHARGE_UNIT, w.[Owner Name];

ノート:

  1. テーブル名に別名を使用したのは、SQL を脳が理解しやすくするためです。
  2. これはGROUP BYクエリでDISTINCTあるため、必要ありません。
  3. WHERE句 condition( ) は、のu.CHARGE_UNIT <> 'CQ'目的を無効にしLEFT JOINます。何が起こるかはわかりませんが、INNER JOIN代わりに使用することもできます。
  4. [Last Modified]長さゼロの文字列も含まれている可能性がある場合は、サブクエリで除外しWHEREます。

    WHERE Len([最終更新日]) > 0

または、単に使用するだけIsDate()です:

WHERE IsDate([Last Modified]) = True

または ...

WHERE IsDate(Left([Last Modified]), 10) = True

[Last Modified]ところで、これはテキスト データ型ではなく日付/時刻型の方が簡単であることに既にお気付きでしょう。何らかの理由でテキストに行き詰まっていると思います。ただし、そうでない場合は、変更を検討してください。

于 2013-02-26T16:16:23.797 に答える
0

これが私が通常これを処理する方法です。私は自由にエイリアスを使用してSQLを短縮し、読みやすくしました。フィールド名にスペースを使用しないことを強くお勧めします。その練習をやめれば、角かっこを使うことを心配する必要はありません。

また、日付の値を文字列として保存していると思います。私は一般的にそれを避けようとします。ほとんどの場合、必要に応じて日付値を文字列に変換する方が、その逆よりも優れていると思います。

以下の関数のvDate引数をバリアントデータ型として残してください。文字列または日付に変更すると、nullを処理できなくなります。エラーが発生する代わりに、SQLは本当に奇妙な結果を生成します。

日付は常に10文字ですか?日付値は、先行ゼロなしで表すことができるため、ゼロが短くなります。

SELECT DISTINCT w.[Owner ID], u.CHARGE_UNIT, w.[Owner Name]
FROM WS_ALL_OBJ as w LEFT JOIN Users as u ON w.[Owner ID] = u.CNAME
WHERE 
    GetLastModDate(w.[Last Modified]) < #2012-11-26#
   And 
    u.CHARGE_UNIT <> 'CQ'
GROUP BY w.[Owner ID], u.CHARGE_UNIT, w.[Owner Name];


'Put this code in a VBA Module
Public Function GetLastModDate(vDate) as Date
    If Nz(vDate, "") = "" Then
        GetLastModDate = #01/12/2050#
    Else
        GetLastModDate = DateValue(Left(vDate), 10)
        End If
End Function
于 2013-02-26T16:04:30.320 に答える