0

私は次のスクリプトの適応をオンラインで見つけました:

CREATE TABLE alphaCodes
(personID INTEGER NOT NULL,
 codes CHAR(10) NOT NULL,
 );

INSERT INTO alphaCodes
VALUES (1, '12300'), (1, '23400'), (1, '45623'), 
       (2, '99900'), (2, '23411'), (2, '78900'), 
       (3, '12300'), (3, '23400'), (3, '45699');
go
CREATE PROCEDURE GetPeopleWithCodes 
(@d1 CHAR(10) = NULL, @d2 CHAR(10) = NULL, 
 @d3 CHAR(10) = NULL, @d4 CHAR(10) = NULL, 
 @d5 CHAR(10) = NULL)
AS BEGIN
--cte for the alphaCodes table
WITH Patient_Diagnosis (personID, codes)
AS (SELECT personID, codes FROM alphaCodes),

codeList (codePattern)
AS
--row constructor makes a table of the variables that will be passed into the stored procedure
(SELECT X.codePattern 
  FROM (VALUES (@d1), (@d2), (@d3), (@d4), (@d5))
        AS X(codePattern)
 WHERE X.codePattern IS NOT NULL)

SELECT DISTINCT personID 
 FROM Patient_Diagnosis AS PD1
 WHERE NOT EXISTS 
       (SELECT *
          FROM codeList
         WHERE NOT EXISTS 
              (SELECT *
                 FROM Patient_Diagnosis AS PD2
                WHERE PD1.personID = PD2.personID
                  AND PD2.codes LIKE codeList.codePattern));
END; 
--for whatever reason, the % wildcard does not and and the _ has to be used
exec dbo.GetPeopleWithCodes '123___'

このストアドプロシージャは最大5つの入力パラメータを取り、基本的に、いくら多くのパラメータを含めた場合の内部結合を返します。だからあなたが実行すると

exec dbo.getpeoplewithcodes '234___' 

1,2,3返されます。実行した場合

exec dbo.getpeoplewithCodes '234____','123___' 

を返し1,3ます。これを実行しようとしたとき、動的SQLを使用して、テーブルへのさまざまな結合を持つテーブルを作成しましたalphaCodes。上記の方法ははるかに高速ですが、1つの問題があります。私は一生それを完全に理解することができません。最後の結合の演算子が好きですが、最初のサブクエリlikeを取得できません。where not exists誰かが何が起こっているのか説明するのを手伝ってもらえますか?alphaCodesテーブルを2つだけ参照し、それでも機能させるにはどうすればよいでしょうか。

4

1 に答える 1

1

私が正しく理解していれば、このコードは、すべての入力パラメータパターンに一致する診断コードを持つすべての患者のリストを返すことを目的としています。

最後のSELECTステートメントは、同じ要件を示す二重否定です。入力パラメーターのリストに一致するコードを持たない行Patient_Diagnosis.Patient_Idのセットに含まれていない行から、すべての値の個別のリストを返します。Patient_Diagnosisこれは、このクエリを作成するための紛らわしい方法です。

以下は十分にテストされていませんが、alphaCodesテーブルを1回スキャンするだけで同じ結果が返されるようです。alphaCodes冗長だったので、CTEを削除しました。

ALTER PROCEDURE GetPeopleWithCodes 
(@d1 CHAR(10) = NULL, @d2 CHAR(10) = NULL, 
 @d3 CHAR(10) = NULL, @d4 CHAR(10) = NULL, 
 @d5 CHAR(10) = NULL)
AS BEGIN
WITH codeList (codePattern)
AS
(SELECT X.codePattern 
  FROM (VALUES (@d1), (@d2), (@d3), (@d4), (@d5))
        AS X(codePattern)
 WHERE X.codePattern IS NOT NULL
)
SELECT pd.PersonId 
FROM codeList cl
JOIN alphaCodes pd
ON pd.codes LIKE cl.codePattern
GROUP BY pd.personID
HAVING COUNT(*) = (SELECT COUNT(*) FROM codeList)
END
GO
于 2012-12-10T22:07:16.133 に答える