将MS Access 2010与链接表一起使用到SQL Server 2005.链接表有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中的Readable值不同或者所有PName中的Editable值不同时才显示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*";
然后将其导出到excel并使用If语句。
请注意,配置文件的数量是动态的。
感谢您的帮助
最新的SQL:
SQL如下,我也尝试将=“True”更改为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;
答案 0 :(得分: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]上查找匹配,在[可读] OR [可编辑]上查找不匹配:
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
...并且可用于为下游流程提供信息。
答案 1 :(得分:0)
您可以使用MS Access向导创建交叉表查询,也可以使用PIVOT创建SQL-Passthrough查询以使SQL Server进行处理。
编辑:根据修订后的问题添加以下内容
您可以在不使用交叉表的情况下离开。这取决于您的查询需要多么灵活,或者您是否可以动态构建查询。对于上面的英国/美国示例,您可以使用:
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