首页 > 解决方案 > 2表1结果,一个棘手的SQL

问题描述

潜伏了多年的stackoverflow,我终于有需要来找你开发大师寻求一点帮助。

语境:

我是一名开发人员,正在使用从 SAP 中提取的信息。我正在提取信息,并使用 H2 数据库在内存中创建两个表。

我的表如下所示:

CREATE TABLE USERS 
(
     SID VARCHAR(255), 
     SYSID VARCHAR(5), 
     MANDT VARCHAR(3), 
     BNAME VARCHAR(255), 
     GLTGV DATE, 
     GLTGB DATE, 
     USTYP VARCHAR(2), 
     LOCNT VARCHAR(3), 
     UFLAG VARCHAR(3), 
     TRDAT DATE, 
     LTIME VARCHAR(255), 
     CLASS VARCHAR(255), 
     PWDCHGDATE DATE, 
     PROFILE VARCHAR(255)
)

CREATE TABLE ROLES 
(
     SID VARCHAR(255), 
     SYSID VARCHAR(5), 
     MANDT VARCHAR(3), 
     UNAME VARCHAR(255), 
     AGR_NAME VARCHAR(255)
)

不用担心定义,为了简单起见,我只是在“模拟”它们。

一个用户可以没有或有多个角色。你怎么把它们绑在一起?

SYSIDMANDT而且BNAMEfrom tableUSERS必须要匹配 table 的内容,ROLEScolumns和(都是同一类型)SYSIDMANDTUNAME

所以我创建了这个查询

SELECT DISTINCT
    t1.SID, 
    t1.SYSID, 
    t1.MANDT, 
    t1.BNAME, 
    t1.GLTGV, 
    t1.GLTGB, 
    t1.USTYP, 
    t1.LOCNT, 
    t1.UFLAG, 
    t1.TRDAT, 
    t1.LTIME, 
    t1.CLASS, 
    t1.PWDCHGDATE, 
    t1.PROFILE
FROM 
    USERS AS t1, 
    ROLES AS t2 
WHERE 
    t1.SYSID = t2.SYSID AND 
    t1.MANDT = t2.MANDT AND 
    t1.BNAME = t2.UNAME AND
    (t2.AGR_NAME = "ZTEST_ROLE")

只要我只按一个角色查询,它就可以很好地工作。

要查询多个角色,我会

SELECT DISTINCT
    t1.SID, 
    t1.SYSID, 
    t1.MANDT, 
    t1.BNAME, 
    t1.GLTGV, 
    t1.GLTGB, 
    t1.USTYP, 
    t1.LOCNT, 
    t1.UFLAG, 
    t1.TRDAT, 
    t1.LTIME, 
    t1.CLASS, 
    t1.PWDCHGDATE, 
    t1.PROFILE
FROM 
    USERS AS t1, 
    ROLES AS t2 
WHERE 
    t1.SYSID = t2.SYSID AND 
    t1.MANDT = t2.MANDT AND 
    t1.BNAME = t2.UNAME AND
    (t2.AGR_NAME = "ZTEST_ROLE" OR t2.AGR_NAME = "ZTEST_ROLE2")

它也有效。如果您想从具有ZTEST_ROLEZTEST_ROLE2作为角色的所有用户那里获取信息,您将使用此查询。

现在,这是我的问题,如果我想选择同时具有角色ZTEST_ROLEZTEST_ROLE2的所有用户,我无法使其工作。我的查询总是返回 0 行

这是我正在使用的查询

SELECT DISTINCT
    t1.SID, 
    t1.SYSID, 
    t1.MANDT, 
    t1.BNAME, 
    t1.GLTGV, 
    t1.GLTGB, 
    t1.USTYP, 
    t1.LOCNT, 
    t1.UFLAG, 
    t1.TRDAT, 
    t1.LTIME, 
    t1.CLASS, 
    t1.PWDCHGDATE, 
    t1.PROFILE
FROM 
    USERS AS t1, 
    ROLES AS t2 
WHERE 
    t1.SYSID = t2.SYSID AND 
    t1.MANDT = t2.MANDT AND 
    t1.BNAME = t2.UNAME AND
    (t2.AGR_NAME = "ZTEST_ROLE" AND t2.AGR_NAME = "ZTEST_ROLE")

我已经玩了一段时间了,我看不出我的错误在哪里

为方便起见,如果您想在线尝试,我一直在使用https://sqliteonline.com/

感谢您的帮助和对长篇文章的歉意

标签: sqljoinh2

解决方案


你不能同时拥有两者

(t2.AGR_NAME = "ZTEST_ROLE" and t2.AGR_NAME = "ZTEST_ROLE2")

在这里你说 t2.AGR_NAME = "ZTEST_ROLE"必须是真的,同时t2.AGR_NAME = "ZTEST_ROLE2"在同一行也必须是真的。

你可以做

(t2.AGR_NAME = "ZTEST_ROLE" and (select AGR_NAME from ROLES where uname = t1.bname and agr_name = "ZTEST_ROLE2") = "ZTEST_ROLE2"))

但我怀疑这是最好的方法。有点老套

这是你的例子

https://dbfiddle.uk/?rdbms=sqlite_3.27&fiddle=18052895bcd6bea155ef01c957a06ff7


推荐阅读