0

SQL Server 2005 へのリンク テーブルで MS Access 2010 を使用します。リンク テーブルには 5 つの列があります。

PName - STRING
OName - STRING
FName - STRING  
Readable - BOOLEAN  
Editable - BOOLEAN  

サンプルデータ:

PName   FName                readable   editable
UK      Case.First_Name         0       0
UK      Case.Last_Name          0       0
UK      Case.Middle_Initial     0       0
UK      Case.Phone_Number       0       0
UK      Case.Username           -1      -1
USA     Case.First_Name         0       0
USA     Case.Last_Name          0       0
USA     Case.Middle_Initial     0       0
USA     Case.Phone_Number       0       0
USA     Case.Username           -1      -1

PName ごとにすべての FName のリストを返すが、読み取り可能な値がすべての PName で異なる場合、または編集可能な値がすべての PName で異なる場合にのみ FName を表示するクエリを作成しようとしています。

出力例:

                      UK           USA
                   Edit|Read    EDIT|Read
Case.First_Name    T   |  T       F | T
Case.UserName      F   |  F       F | T

上記の「Case.First_Name」は英国では編集可能ですが、米国では編集できないため、この行を表示したい理由があります

Case.UserName は英国では読み取り可能ではありませんが、米国では読み取り可能であるため、この行を表示したい理由

出力してはいけないもの:

                      UK           USA
                   Edit|Read    EDIT|Read
Case.First_Name    T   |  T       T | T
Case.UserName      F   |  F       F | F

上記の行は両方とも、英国と米国の両方で同一の読み取り可能性と編集可能性を持っているため、これらの行を表示したくありません。

以下のクエリは、必要な生データを取得し、ピボット テーブルに変換できます。

SELECT PName, FName, Readable, Editable
FROM ProfileFLS
WHERE PName Like "U*";

これは、If ステートメントを使用して Excel にエクスポートされます。

プロファイルの数は動的であることに注意してください。

ご協力いただきありがとうございます

最新の SQL:

SQL is as follows, I have also tried changing the ="True" to 0

TRANSFORM Sum(IIf(dbo_ProfileFLS.readable="TRUE","Read_True","Read_False")) AS Readable
SELECT dbo_ProfileFLS.fieldname
FROM dbo_ProfileFLS
WHERE (((dbo_ProfileFLS.objectname)="Case") AND ((dbo_ProfileFLS.Profile) Like "UK*"))
GROUP BY dbo_ProfileFLS.fieldname, dbo_ProfileFLS.readable
PIVOT dbo_ProfileFLS.Profile;
4

2 に答える 2

2

質問を編集していただきありがとうございます。物事は今、はるかに明確です。

実際の結果が得られるように、サンプル データを微調整することから始めましょう。

PName   FName               readable    editable
UK      Case.First_Name     0           -1
UK      Case.Last_Name      0           0
UK      Case.Middle_Initial 0           0
UK      Case.Phone_Number   0           0
UK      Case.Username       -1          -1
USA     Case.First_Name     0           0
USA     Case.Last_Name      0           0
USA     Case.Middle_Initial -1          0
USA     Case.Phone_Number   0           0
USA     Case.Username       -1          -1
Canada  Case.First_Name     0           0
Canada  Case.Last_Name      0           -1
Canada  Case.Middle_Initial 0           0
Canada  Case.Phone_Number   0           0
Canada  Case.Username       0           0

ここで、次のクエリを検討してください。[FName] での一致と、[読み取り可能] または [編集可能] での不一致を探す自己結合です。

SELECT p1.FName, 
    p1.PName AS PName1, p1.readable AS read1, p1.editable AS edit1,
    p2.PName AS PName2, p2.readable AS read2, p2.editable AS edit2
FROM permissionsTbl p1 INNER JOIN permissionsTbl p2
    ON p1.FName=p2.FName 
        AND (p1.readable<>p2.readable OR p1.editable<>p2.editable)
ORDER BY 1, 2 ;

戻る

FName               PName1  read1   edit1   PName2  read2   edit2
Case.First_Name     Canada  0       0       UK      0       -1
Case.First_Name     UK      0       -1      Canada  0       0
Case.First_Name     UK      0       -1      USA     0       0
Case.First_Name     USA     0       0       UK      0       -1
Case.Last_Name      Canada  0       -1      USA     0       0
Case.Last_Name      Canada  0       -1      UK      0       0
Case.Last_Name      UK      0       0       Canada  0       -1
Case.Last_Name      USA     0       0       Canada  0       -1
Case.Middle_Initial Canada  0       0       USA     -1      0
Case.Middle_Initial UK      0       0       USA     -1      0
Case.Middle_Initial USA     -1      0       UK      0       0
Case.Middle_Initial USA     -1      0       Canada  0       0
Case.Username       Canada  0       0       USA     -1      -1
Case.Username       Canada  0       0       UK      -1      -1
Case.Username       UK      -1      -1      Canada  0       0
Case.Username       USA     -1      -1      Canada  0       0

読み取り権限または編集権限が一致しないすべてのケースを示します。

これを微調整して、上記のリストに表示された [FName] 値の DISTINCT リストを作成します...

SELECT DISTINCT p1.FName 
FROM permissionsTbl p1 INNER JOIN permissionsTbl p2
    ON p1.FName=p2.FName 
        AND (p1.readable<>p2.readable OR p1.editable<>p2.editable) ;

...そして、それをサブクエリとして使用して、元のテーブルからそれらの FName 行を抽出します

SELECT * FROM permissionsTbl
WHERE FName IN
(
    SELECT DISTINCT p1.FName 
    FROM permissionsTbl p1 INNER JOIN permissionsTbl p2
        ON p1.FName=p2.FName 
            AND (p1.readable<>p2.readable OR p1.editable<>p2.editable)
) ;

...戻ります...

PName   FName               readable    editable
UK      Case.First_Name     0           -1
UK      Case.Last_Name      0           0
UK      Case.Middle_Initial 0           0
UK      Case.Username       -1          -1
USA     Case.First_Name     0           0
USA     Case.Last_Name      0           0
USA     Case.Middle_Initial -1          0
USA     Case.Username       -1          -1
Canada  Case.First_Name     0           0
Canada  Case.Last_Name      0           -1
Canada  Case.Middle_Initial 0           0
Canada  Case.Username       0           0

...そして、下流のプロセスにフィードするために使用できます。

于 2013-04-04T17:11:12.033 に答える
0

MS Access ウィザードを使用してクロス集計クエリを作成するか、PIVOT を使用して SQL パススルー クエリを作成し、SQL Server に処理をさせることができます。

編集:改訂された質問に基づいて以下を追加

クロス集計を使用せずに回避できる場合があります。クエリに必要な柔軟性や、その場でクエリを作成できるかどうかによって異なります。上記の UK/USA の例では、以下を使用できます。

SELECT dbo_ProfileFLS.FName,
       dbo_ProfileFLS.Readable AS [UK Read], 
       dbo_ProfileFLS.Editable AS [UK Edit],
       dbo_ProfileFLS_1.Readable AS [USA Read],
       dbo_ProfileFLS_1.Editable AS [USA Edit]
FROM   dbo_ProfileFLS
INNER JOIN dbo_ProfileFLS AS dbo_ProfileFLS_1
ON     dbo_ProfileFLS.FName = dbo_ProfileFLS_1.FName
WHERE  dbo_ProfileFLS.PName="UK"
  AND  dbo_ProfileFLS_1.PName="USA" 
  AND  (dbo_ProfileFLS.Readable<>[dbo_ProfileFLS_1].[Readable]
       OR dbo_ProfileFLS.Editable<>[dbo_ProfileFLS_1].[Editable]);

本当にクロス集計を使用したい場合、問題は値に列しか使用できないことです (既に見たように)。これは、読み取り可能フィールドと編集可能フィールドを連結することで解決できます。クロス集計は Group By を使用しますが、実際には単純な値が必要なため、集計関数 First を使用する必要があります。例えば:

TRANSFORM First(Readable & " | " & Editable) AS ReadEdit
SELECT dbo_ProfileFLS.FName
FROM dbo_ProfileFLS
GROUP BY dbo_ProfileFLS.FName
PIVOT dbo_ProfileFLS.PName & " Read | Edit";

もちろん、このクエリは完全なテーブルを取ります。正しい値のみを取得するには、フィルターとして使用する最初のクエリのバリエーションが必要です。

SELECT dbo_ProfileFLS.ID AS UK_ID,
       dbo_ProfileFLS_1.ID AS USA_ID
FROM   dbo_ProfileFLS
INNER JOIN dbo_ProfileFLS AS dbo_ProfileFLS_1 
ON     dbo_ProfileFLS.FName = dbo_ProfileFLS_1.FName
WHERE  dbo_ProfileFLS.PName="UK"
  AND  dbo_ProfileFLS_1.PName="USA" 
  AND  (dbo_ProfileFLS.Readable<>[dbo_ProfileFLS_1].[Readable]
       OR dbo_ProfileFLS.Editable<>[dbo_ProfileFLS_1].[Editable]);

これに crosstabFilter という名前を付ける場合は、dbo_ProfileFLS とクロス結合し、次の条件を使用します。

WHERE crosstabFilter.UK_ID=ID OR crosstabFilter.USA_ID=ID
于 2013-04-04T14:26:45.427 に答える