2012-02-13 60 views
1

我需要將字段過濾爲日期,但該字段未輸入日期或日期時間。在未輸入日期的日期字段上過濾

SELECT champ_save_id, element_id, valeur 
FROM g_champ_save AS cs 
INNER JOIN g_champ AS c ON cs.champ_id = c.champ_id 
WHERE cs.valeur <> '' AND NOT cs.valeur IS NULL 
AND c.champ_code = 'qualif_valide_qualif_fin' 
AND CONVERT(datetime, cs.valeur, 103) <= @filterdate 

它拋出一個錯誤(Conversion failed when converting datetime from character string),除非我的評論的最後一行。
據我所知,SQL優化器首先在每個valeur字段上執行CONVERT函數,然後在其他條件下過濾,然後進行連接。所以它會嘗試CONVERT字段中的「常規」文本,所以它當然不起作用。

我嘗試過一個CTE,但它做的事情完全一樣。

WITH valeurs AS (
    SELECT champ_save_id, element_id, valeur 
    FROM g_champ_save AS cs 
    INNER JOIN g_champ AS c ON cs.champ_id = c.champ_id 
    WHERE cs.valeur <> '' AND NOT cs.valeur IS NULL 
    AND c.champ_code = 'qualif_valide_qualif_fin' 
    AND ISDATE(convert(datetime, cs.valeur, 103)) = 1 
) 
SELECT * FROM valeurs 
WHERE CONVERT(datetime, valeur, 103) <= @filterdate 

你有什麼想法,這將讓我切切第一返回一個包含日期字段,然後過濾他們?

該表的設計類似(縮短清晰度):

CREATE TABLE g_champ (
    champ_id int IDENTITY(1,1) NOT NULL, 
    type_id int NOT NULL, -- defines the type : text, checkbox, date, etc 
    champ_code nvarchar(50) NULL, 
    champ_label nvarchar(max) NULL 
) 

CREATE TABLE g_champ_save (
    champ_save_id int IDENTITY(1,1) NOT NULL, 
    champ_id int NOT NULL, 
    element_id int NULL, 
    valeur nvarchar(max) NULL 
) 

感謝

+0

CONVERT(datetime,cs.valeur,103)導致錯誤。請檢查該列中的數據,值應該是datetime,即2012013或某個日期值字符串可以轉換爲DateTime。 – 2012-02-13 14:06:19

回答

2

我認爲你需要使用IsDate

SELECT champ_save_id, element_id, valeur 
FROM g_champ_save AS cs 
INNER JOIN g_champ AS c ON cs.champ_id = c.champ_id 
WHERE cs.valeur <> '' AND NOT cs.valeur IS NULL 
AND c.champ_code = 'qualif_valide_qualif_fin' 
AND CONVERT(datetime, case IsDate(cs.valeur) when 1 then cs.valeur end, 103) 
    <= @filterdate 
+1

+1:雖然這假定OP要忽略任何未能轉換的值。似乎更可能(對我)OP應該使用ISDATE()來查找違規記錄然後糾正它們,而不是忽略它們? – MatBailie 2012-02-13 14:18:33

+0

從我的理解'ISDATE()'函數將返回true如果該值可以轉換爲任何格式的日期,所以這仍然可以失敗,如果該值不能轉換爲103日期時間格式 – Lamak 2012-02-13 14:33:18

+0

是的,我試過了,但IsDate()測試美國格式(m/d/y),並且我的日期採用法文/英文格式(d/m/y)。因此31/1/2012不被視爲日期。 – thomasb 2012-02-13 15:14:19

0

試試這個:我知道這個工程的MSSQL和MySQL,但不知道什麼DB烏爾使用

SELECT champ_save_id, element_id, valeur 
FROM g_champ_save AS cs 
INNER JOIN g_champ AS c ON cs.champ_id = c.champ_id 
WHERE cs.valeur <> '' AND NOT cs.valeur IS NULL 
AND c.champ_code = 'qualif_valide_qualif_fin' 
AND Date(cs.valeur) <= @filterdate 
+0

不能:/''日期'不是一個公認的內置函數名稱.'。我使用SQL Server 2005/2008。 – thomasb 2012-02-13 14:06:29

1

嘗試的HAVING子句中,並使用IS NOT NULLNOT cs.valeur IS NULL

SET DATEFORMAT dmy; 
GO 
SELECT champ_save_id, element_id, valeur 
    FROM g_champ_save AS cs INNER JOIN g_champ AS c 
     ON cs.champ_id = c.champ_id 
WHERE cs.valeur <> '' AND 
     cs.valeur IS NOT NULL AND 
     c.champ_code = 'qualif_valide_qualif_fin' 
HAVING CONVERT(datetime, cs.valeur, 103) <= @filterdate; 
+0

仍然沒有運氣...它給我同樣的錯誤。 – thomasb 2012-02-13 15:19:09

+1

@ cosmo0我加了SET DATEFORMAT dmy;它現在有效嗎? – 2012-02-13 15:36:16

+0

不,但謝謝你的提示! – thomasb 2012-02-13 15:40:54

0

下面的查詢應該做的工作,無需轉換錯誤。注意:無效的時間戳將被忽略。

SELECT 
champ_save_id, element_id, valeur 
FROM 
(
SELECT champ_save_id, element_id, valeur 
FROM g_champ_save AS cs 
INNER JOIN (SELECT c.champ_id FROM g_champ c WHERE c.champ_code = 'qualif_valide_qualif_fin') AS c ON cs.champ_id = c.champ_id 
WHERE cs.valeur <> '' AND NOT cs.valeur IS NULL AND ISDATE(cs.valeur) 
) sub 
WHERE CONVERT(datetime, cs.valeur, 103) <= @filterdate 

更新

做了一些改變,這將返回預期的結果。

SET DATEFORMAT dmy;

SET DATEFORMAT dmy; 

SELECT 
champ_save_id, element_id, valeur, CONVERT(datetime, sub.valeur, 103) 
FROM 
(
SELECT champ_save_id, element_id, valeur 
FROM (SELECT 1 champ_id, 1 champ_save_id, 1 element_id, '30/1/2012' valeur) AS cs 
INNER JOIN (SELECT c.champ_id FROM (SELECT 1 champ_id, 'qualif_valide_qualif_fin' champ_code) c WHERE c.champ_code = 'qualif_valide_qualif_fin') AS c ON cs.champ_id = c.champ_id 
WHERE cs.valeur <> '' AND NOT cs.valeur IS NULL AND ISDATE(cs.valeur) = 1 
) sub 
WHERE CONVERT(datetime, sub.valeur, 103) <= '01/02/2012' 
+0

不,顯然子查詢和CTE是一樣的。 – thomasb 2012-02-13 15:17:14

+0

@ cosmo0我加了'SET DATEFORMAT dmy;'它現在有效嗎? – 2012-02-13 15:35:10