我正在尝试对三个不同的表进行查询。
变量表
"area"
,"rounds"
和
"days"
变量所属。变量表还包含一个pk列。
pk用于确定记录属于哪个变量。面积表
"name"
的信息以及
区域所属的"role"
。为用户分配一个角色,然后
访问特定区域。记录表
"value"
,"alarmed"
和"alarmType"
列。您可以搜寻
获取基于变量round和day的记录。我正在尝试在某天和某天为用户查询所有变量。 我想显示所有变量,无论是否找到记录。当前,我有一个查询,该查询仅返回具有记录的变量,而不返回没有记录的变量。
如果没有记录,则value, alarmed, and alarmType
列应为空。
这是我到目前为止构建的查询:
SELECT DISTINCT variable.name, area.name AS "areaName", variable.pk, CAST(record.value AS TEXT) AS "value", record.alarmed, record.alarmType
FROM variable, area, record
WHERE variable.round LIKE '%,1,%'
AND variable.day LIKE '%,3,%'
AND variable.readOnly = 0
AND variable.area IN (SELECT pk
FROM area
WHERE role = (SELECT role
FROM user
WHERE userName LIKE 'Leo'))
AND variable.area = area.pk
AND record.value = (SELECT CASE WHEN COUNT() < 1 THEN NULL
ELSE CAST(value AS TEXT) END
FROM record
WHERE round = 1
AND day = "11-14-2018"
AND variable = variable.pk)
ORDER BY variable.area, variable.position ASC;
当前它返回如下内容:
还有更多的变量,即使没有记录,我也想知道如何显示它们。
答案 0 :(得分:2)
我想我明白了您要做什么。关键是使用联接(特别是OUTER联接),而不是尝试将所有表混在一起,然后找到相似之处。还有LEFT
,RIGHT
和INNER
种口味(有关这些here和here的更多信息),具体取决于您认为“完整”或“主”数据集-查询的起点。
这是我了解您的人际关系的方式(如果我错了,请告诉我):
record.variable --> variable.pk
variable.area --> area.pk
area.role --> user.role
在您的情况下,您说您需要variable
表中的所有记录,因此我将从此开始:
SELECT v.*
FROM variable v;
然后,您可能会找到与特定USER相关的所有AREA记录。使用INNER
联接仅查找联接两边都存在的记录:
SELECT a.*, u.*
FROM area a
INNER JOIN user u -- Define the table to join
ON a.role = u.role -- Which columns contain keys to match on
WHERE u.userName = 'Leo';
WHERE过滤器适用于user
表,但是因为我们仅从area
表中查询与用户匹配的记录,所以这限制了{{1} }表。
下一步是使用另一个area
连接再次将这两个提取物连接在一起,以找到交集-在连接的两边都存在的匹配项:
INNER
现在,我们通过添加SELECT v.*, a.*, u.*
FROM variable v -- New starting point
INNER JOIN area a
ON a.pk = v.area
INNER JOIN user u
ON a.role = u.role
WHERE u.userName = 'Leo';
子句来查找某天的所有记录:
WHERE
接下来,我们使用SELECT v.*, a.*, u.*
FROM variable v
INNER JOIN area a
ON a.pk = v.area
INNER JOIN user u
ON a.role = u.role
WHERE u.userName = 'Leo'
AND v.round = 1 -- Add filters for "round"
AND v.day = '11-14-2018'; -- and "day" columns
联接为我们提供“左侧”表中的所有记录,以及在“右侧”(“记录”表)中找到的所有匹配项;如果没有,则为NULL匹配:
LEFT
来自SELECT v.name
,a.name as "areaName"
,CAST(r.value as TEXT) as "value"
,r.alarmed
,r.alarmType
FROM variable v
INNER JOIN area a
ON v.area = a.pk
INNER JOIN user u
ON a.role = u.role
LEFT JOIN record r -- LEFT is important here
ON v.pk = r.variable
WHERE u.userName = 'Leo'
AND v.round = 1
AND v.day = '11-14-2018'
ORDER BY v.area, v.position;
连接(INNER
+ variable
+ area
)的结果成为此连接的“左侧”,而user
成为该连接的“左侧”。 “右边。使用record
连接声明我们希望从左侧开始的所有记录,无论它们是否在右侧都匹配。
我没有数据集可用于测试,因此请原谅我犯的任何错误。
希望这说明如何将联接用于消除行并向结果添加数据(列),而不必进行单个查询或诉诸子查询(使用LEFT
或IN
)。