SQL:用一个table作为自己的标准
SQL: Using one table as a criteria for itself
我正在尝试使用 table 的参数作为其自身的标准,但我的 sql 语句不太正确。这似乎是一个相对简单的查询;我正在为我的条件使用子查询,但它没有过滤掉我的 table.
上的其他行
背景:
制造生产车间:我现在有一群机械师在他们的机器上 运行 作业 (JobNum) 的操作 (OprSeq)。从保存所有劳动力记录的 LaborDtl table,我可以看到当前活跃的劳动力 (ActiveTrans = 1)。有了这个活跃劳动力的标准,我想总结每个活跃劳动力条目的所有过去的劳动力交易。所以我需要一个非活动劳动 activity 的 LaborDtl table 以及来自相同 table 的活动劳动标准。
代码:
这是我的 'criteria' 子查询:
SELECT
LaborDtl.JobNum,
LaborDtl.OprSeq
FROM Erp.LaborDtl
WHERE LaborDtl.ActiveTrans = 1
returns 活跃交易,这是第一对(按工作排序):
Job Operation
000193 90
000457 70
000457 70
020008-1 140
020008-2 130
020010 60
020035 130
020175 40
020175-2 50
020186 80
020199 10
020203 50
020212 40
020258 60
020272 10
020283 30
020298 10
020299 30
下面是完整的 SQL 语句,上面嵌入了查询:
SELECT
LaborDtl.JobNum,
LaborDtl.OprSeq as "Op",
SUM(LaborDtl.LaborQty) as "Total Labor"
FROM Erp.LaborDtl
WHERE EXISTS
(
SELECT
LaborDtl.Company,
LaborDtl.JobNum,
LaborDtl.OprSeq
FROM Erp.LaborDtl
WHERE LaborDtl.ActiveTrans = 1 --Labor table of just current activity
)
GROUP BY LaborDtl.JobNum, LaborDtl.OprSeq
我希望只看到我的子查询中存在的作业和操作编号,但我得到的作业和操作在我的子查询中不存在。这是前 10 个(注意,根据我的标准,第一个 JobNum 应该是 000193)
JobNum Op Total Labor
0 0.00000000
000004 1 32.00000000
000019 1 106.00000000
000029 1 175.00000000
000143 1 85.00000000
000164 1 58.00000000
000181 1 500.00000000
000227 1 116.00000000
000421 1 154.00000000
000458 1 67.00000000
在不知道 RDBMS 供应商和版本的情况下,这是我能做的最好的事情:
SELECT
t1.JobNum,
t1.OprSeq as "Op",
SUM(t1.LaborQty) as "Total Labor"
FROM Erp.LaborDtl t1
WHERE EXISTS
(
SELECT 1
FROM Erp.LaborDtl t2
WHERE t2.ActiveTrans = 1 --Labor table of just current activity
and t2.Company = t1.Company
and t2.JobNum = t1.JobNum
and t2.OprSeq = t1.OprSeq
)
GROUP BY t1.JobNum, t1.OprSeq
您缺少将外部查询和内部查询联系在一起的某些条件。现在,如果没有该条件,内部查询只是 returns "true",因为存在活动活动的作业,因此会返回外部查询中的所有行。请注意,您必须向 table 添加别名,因为内部和外部查询使用相同的 table:
SELECT a.JobNum, a.OprSeq as "Op", SUM(a.LaborQty) as "Total Labor"
FROM Erp.LaborDtl a
WHERE EXISTS (SELECT * -- The select list doesn't really matter here
FROM Erp.LaborDtl b
WHERE a.JobNum = b.JobNum AND -- Here!
a.OprSeq = b.OprSeq AND -- And here!
b.ActiveTrans = 1 -- Labor table of just current activity
)
GROUP BY a.JobNum, a.OprSeq
但是请注意,有一种更简单的(恕我直言)方法。由于您按 JobNum
和 OprSeq
分组,您可以只计算活动事务的数量并使用 having
子句仅查询至少具有一个活动事务的那些:
SELECT JobNum, OprSeq as "Op", SUM(LaborQty) as "Total Labor"
FROM Erp.LaborDtl
GROUP BY JobNum, OprSeq
HAVING COUNT(CASE ActiveTrans WHEN 1 THEN 1 END) > 0
我正在尝试使用 table 的参数作为其自身的标准,但我的 sql 语句不太正确。这似乎是一个相对简单的查询;我正在为我的条件使用子查询,但它没有过滤掉我的 table.
上的其他行背景:
制造生产车间:我现在有一群机械师在他们的机器上 运行 作业 (JobNum) 的操作 (OprSeq)。从保存所有劳动力记录的 LaborDtl table,我可以看到当前活跃的劳动力 (ActiveTrans = 1)。有了这个活跃劳动力的标准,我想总结每个活跃劳动力条目的所有过去的劳动力交易。所以我需要一个非活动劳动 activity 的 LaborDtl table 以及来自相同 table 的活动劳动标准。
代码:
这是我的 'criteria' 子查询:
SELECT
LaborDtl.JobNum,
LaborDtl.OprSeq
FROM Erp.LaborDtl
WHERE LaborDtl.ActiveTrans = 1
returns 活跃交易,这是第一对(按工作排序):
Job Operation
000193 90
000457 70
000457 70
020008-1 140
020008-2 130
020010 60
020035 130
020175 40
020175-2 50
020186 80
020199 10
020203 50
020212 40
020258 60
020272 10
020283 30
020298 10
020299 30
下面是完整的 SQL 语句,上面嵌入了查询:
SELECT
LaborDtl.JobNum,
LaborDtl.OprSeq as "Op",
SUM(LaborDtl.LaborQty) as "Total Labor"
FROM Erp.LaborDtl
WHERE EXISTS
(
SELECT
LaborDtl.Company,
LaborDtl.JobNum,
LaborDtl.OprSeq
FROM Erp.LaborDtl
WHERE LaborDtl.ActiveTrans = 1 --Labor table of just current activity
)
GROUP BY LaborDtl.JobNum, LaborDtl.OprSeq
我希望只看到我的子查询中存在的作业和操作编号,但我得到的作业和操作在我的子查询中不存在。这是前 10 个(注意,根据我的标准,第一个 JobNum 应该是 000193)
JobNum Op Total Labor
0 0.00000000
000004 1 32.00000000
000019 1 106.00000000
000029 1 175.00000000
000143 1 85.00000000
000164 1 58.00000000
000181 1 500.00000000
000227 1 116.00000000
000421 1 154.00000000
000458 1 67.00000000
在不知道 RDBMS 供应商和版本的情况下,这是我能做的最好的事情:
SELECT
t1.JobNum,
t1.OprSeq as "Op",
SUM(t1.LaborQty) as "Total Labor"
FROM Erp.LaborDtl t1
WHERE EXISTS
(
SELECT 1
FROM Erp.LaborDtl t2
WHERE t2.ActiveTrans = 1 --Labor table of just current activity
and t2.Company = t1.Company
and t2.JobNum = t1.JobNum
and t2.OprSeq = t1.OprSeq
)
GROUP BY t1.JobNum, t1.OprSeq
您缺少将外部查询和内部查询联系在一起的某些条件。现在,如果没有该条件,内部查询只是 returns "true",因为存在活动活动的作业,因此会返回外部查询中的所有行。请注意,您必须向 table 添加别名,因为内部和外部查询使用相同的 table:
SELECT a.JobNum, a.OprSeq as "Op", SUM(a.LaborQty) as "Total Labor"
FROM Erp.LaborDtl a
WHERE EXISTS (SELECT * -- The select list doesn't really matter here
FROM Erp.LaborDtl b
WHERE a.JobNum = b.JobNum AND -- Here!
a.OprSeq = b.OprSeq AND -- And here!
b.ActiveTrans = 1 -- Labor table of just current activity
)
GROUP BY a.JobNum, a.OprSeq
但是请注意,有一种更简单的(恕我直言)方法。由于您按 JobNum
和 OprSeq
分组,您可以只计算活动事务的数量并使用 having
子句仅查询至少具有一个活动事务的那些:
SELECT JobNum, OprSeq as "Op", SUM(LaborQty) as "Total Labor"
FROM Erp.LaborDtl
GROUP BY JobNum, OprSeq
HAVING COUNT(CASE ActiveTrans WHEN 1 THEN 1 END) > 0