7

Y / Nフラグを作成したいと思います。ここで、Yは、特定の行のすべての列のすべての有効な値が等しいことを示し、それ以外の場合はNを示します。null、ブランク、またはすべてゼロを含む列を考慮から除外する必要があります。仮定する:

CREATE TABLE z_test
(ID INT NOT NULL,
D1 VARCHAR(8)NULL,
D2 VARCHAR(8)NULL,
D3 VARCHAR(8)NULL,
D4 VARCHAR(8)NULL,
DFLAG CHAR(1)NULL)

INSERT INTO z_test VALUES (1,NULL,' ','000000','00000000',NULL)
INSERT INTO z_test VALUES (1,'20120101','0000','20120101','00000000',NULL)
INSERT INTO z_test VALUES (2,'20100101','20100101','20100101','20100101',NULL)
INSERT INTO z_test VALUES (2,'00000000','20090101','0','20090101',NULL)
INSERT INTO z_test VALUES (3,'00000000','20090101',NULL,'20120101',NULL)
INSERT INTO z_test VALUES (3,'20100101',' ',NULL,'20100101',NULL)

必要な出力(D1からD4を除くが、ドロップしたくない)は次のとおりです。

ID       DFLAG
---------------
1        N
1        Y
2        Y
2        Y
3        N
3        Y

このクエリはあまり頻繁に実行されないため、速度は問題ではありませんが、大きなテーブル上にあります。

どんなポインタや提案も大歓迎です!!

4

5 に答える 5

7
SELECT ID, 
       CASE 
         WHEN C = 1 THEN 'Y' 
         ELSE 'N' 
       END AS DFLAG 
FROM   z_test 
       CROSS APPLY (SELECT COUNT(DISTINCT D) C 
                    FROM   (VALUES(D1), 
                                  (D2), 
                                  (D3), 
                                  (D4)) V(D) 
                    WHERE  LEN(D) > 0 /*Excludes blanks and NULLs*/
                         AND D LIKE '%[^0]%'/*Excludes ones with only zero*/) CA 
于 2012-05-16T21:23:51.330 に答える
5

これは機能します:

select case when
    (D1 is null OR D2 is null OR LEN(REPLACE(D1,'0',''))=0 OR LEN(REPLACE(D2,'0',''))=0 OR D1=D2)
AND (D1 is null OR D3 is null OR LEN(REPLACE(D1,'0',''))=0 OR LEN(REPLACE(D3,'0',''))=0 OR D1=D3)
AND (D1 is null OR D4 is null OR LEN(REPLACE(D1,'0',''))=0 OR LEN(REPLACE(D4,'0',''))=0 OR D1=D4)
AND (D2 is null OR D3 is null OR LEN(REPLACE(D2,'0',''))=0 OR LEN(REPLACE(D3,'0',''))=0 OR D2=D3)
AND (D2 is null OR D4 is null OR LEN(REPLACE(D2,'0',''))=0 OR LEN(REPLACE(D4,'0',''))=0 OR D2=D4)
AND (D3 is null OR D4 is null OR LEN(REPLACE(D3,'0',''))=0 OR LEN(REPLACE(D4,'0',''))=0 OR D3=D4)
AND (LEN(REPLACE(D1,'0','')) > 0
     OR LEN(REPLACE(D2,'0','')) > 0
     OR LEN(REPLACE(D3,'0','')) > 0
     OR LEN(REPLACE(D4,'0','')) > 0)
THEN 'Y' ELSE 'N' END
from z_test

これがsqlfiddleへのリンクです。

于 2012-05-16T20:59:24.743 に答える
1

これを試して:

DECLARE @z_test table
(ID INT NOT NULL,
D1 VARCHAR(8)NULL,
D2 VARCHAR(8)NULL,
D3 VARCHAR(8)NULL,
D4 VARCHAR(8)NULL,
DFLAG CHAR(1)NULL)

INSERT INTO @z_test VALUES (1,NULL,' ','000000','00000000',NULL)
INSERT INTO @z_test VALUES (1,'20120101','0000','20120101','00000000',NULL)
INSERT INTO @z_test VALUES (2,'20100101','20100101','20100101','20100101',NULL)
INSERT INTO @z_test VALUES (2,'00000000','20090101','0','20090101',NULL)
INSERT INTO @z_test VALUES (3,'00000000','20090101',NULL,'20120101',NULL)
INSERT INTO @z_test VALUES (3,'20100101',' ',NULL,'20100101',NULL)

;WITH Fixed AS
(SELECT --converts columns with all zeros and any spaces to NULL
     ID
         ,NULLIF(NULLIF(D1,''),0) AS D1
         ,NULLIF(NULLIF(D2,''),0) AS D2
         ,NULLIF(NULLIF(D3,''),0) AS D3
         ,NULLIF(NULLIF(D4,''),0) AS D4
    FROM @z_test
)
SELECT --final result set
    ID,
    CASE 
        WHEN COALESCE(D1,D2,D3,D4) IS NULL THEN 'N' --all columns null
        WHEN (D1 IS NULL OR D1=COALESCE(D1,D2,D3,D4)) --all columns either null or the same
            AND (D2 IS NULL OR D2=COALESCE(D1,D2,D3,D4))
            AND (D3 IS NULL OR D3=COALESCE(D1,D2,D3,D4))
            AND (D4 IS NULL OR D4=COALESCE(D1,D2,D3,D4))
            THEN 'Y'
        ELSE 'N'
    END
    FROM Fixed

出力:

ID          
----------- ----
1           N
1           Y
2           Y
2           Y
3           N
3           Y

(6 row(s) affected)
于 2012-05-16T21:07:13.093 に答える
0

このための関数を作成できます。

create function fnRowValid(@d1 varchar, @d2 varchar...)
returns bit ------ 1 for true and 0 for false
begin

  declare table @validvalue (val varchar)

  if isdate(d1) = 0 and isdate(d1) = 0 and ...
    return 0

  if isdate(@d1)
    insert into @validvalue (val) values (@d1)
  if isdate(@d2)
    insert into @validvalue (val) values (@d2)
  if isdate(@d3)
    insert into @validvalue (val) values (@d3)
  ...


  if exists (select 1 from @validvalue)
    if (select count(distinct val) from @validvalue) = 1
      return 1

  return 0

end

次に、これをupdateステートメントで使用できます...

update z_test
set dflag = dbo.fnRowValid(d1,d2,d3..)

これで私を怒らせないでください...私は明らかにこのコードをテストしませんでした。そして、これは私の頭に浮かんだ最初の解決策です...本当のエレガントではありませんが、うまくいくはずです。関数でもテーブル変数を使用できるとは思いません。醜い解決策について申し訳ありません。

于 2012-05-16T21:17:03.210 に答える
0
With RnkSource As
  (
    Select Id, D1, D2, D3, D4, DFlag
      , Row_Number() Over ( Order By Id ) As RowNum
    From z_test
  )
  , Source As
  (
    Select RowNum, Id, 'D1' As Col, D1 As Val
    From RnkSource
    Union All
    Select RowNum, Id, 'D2', D2
    From RnkSource
    Union All
    Select RowNum, Id, 'D3', D3
    From RnkSource
    Union All
    Select RowNum, Id, 'D4', D4
    From RnkSource
  )
Select Id
  , Case When Count(*) = 4 Then 'Y' Else 'N' End As DFLAG
From Source As S
Where Len(Val) > 0
Group By RowNum, Id

SQLフィドルバージョン

于 2012-05-16T21:52:14.210 に答える