英文:
Is it possible to use CTE for the data exist in one table, not 2?
问题
以下是您要翻译的部分:
"Imagine a factory for producing credit/debit cards, where the card will go through different stages of production. For example, a card will go through a molding
stage, then will pass through a printing
stage. Sometimes if there's a problem, the card will be sent back to the previous stages.
I want to write a query to find all cards that went through printing
but were sent back to molding
(since molding
is prior to printing
).
What would be the way to "link" the cards' data that exist in both stages (they are in the same table):"
请注意,代码部分已被排除,只提供翻译的问题描述和要求。
英文:
Imagine a factory for producing credit/debit cards, where the card will go through different stages of production. For example, a card will go through a molding
stage, then will pass through a printing
stage. Sometimes if there's problem the card will be sent back to the previous stages.
I want to write a query to find all cards that went through printing
but is sent back molding
(since molding
is prior to printing
).
What would be the way to "link" the cards data that exist both stages (they are in the same table):
select distinct barcode
from [Audit]..Stages (nolock)
where clientID = 'AmericanExpress'
and stagename = 'printing'
and Description <> 'Success'
select distinct barcode
from [Audit]..Stages (nolock)
where clientID = 'AmericanExpress'
and stagename = 'Molding'
and Description = 'Success'
I'm confused on the right way to "filter" since all the data exist in 1 table, not 2.
;
with failure as (
select distinct barcode
from [Audit]..Stages (nolock)
where clientID = 'AmericanExpress'
and stagename = 'printing'
and Description <> 'Success'
)
success as (select distinct jt.jtpsid, jt.jtbarcode
from failure
with failure as (
select distinct barcode
from [Audit]..Stages (nolock)
where clientID = 'AmericanExpress'
and stagename = 'Molding'
and Description = 'Success')
答案1
得分: 0
你想选择所有当前处于"molding"阶段的卡片,并且还有一个"printing"阶段,其中该阶段的日期未成功。要做到这一点,您可以将表与自身连接:
SELECT DISTINCT barcode
FROM [Audit]..Stages s0
INNER JOIN [Audit]..Stages s1 ON s1.barcode = s0.barcode
AND s1.stagename = 'printing'
AND s1.Description <> 'Success'
WHERE s0.stagename = 'molding'
AND s0.Description = 'success'
如果您还能知道"s1"记录的日期比"s0"记录的日期早,那就更好了,因为我预计还有一些"in-process"阶段也不是成功的。
此外,请去掉那些"(nolock)"提示。它们可能没有达到您所期望的效果...至少不是以安全的方式。"(nolock)"可以通过忽略某些锁定来加快数据库的速度。但这会带来读取陈旧数据的风险。问题在于,_仅在读取陈旧数据的风险较高的情况下,性能才会得到改善。如果没有陈旧数据,那么就不会有要忽略的锁定。
英文:
You want to select all cards that are currently in the molding
stage, and also have a printing
stage where the date for the stage did not succeed. To do this you can JOIN
the table to itself:
SELECT distinct barcode
FROM [Audit]..Stages s0
INNER JOIN [Audit]..Stages s1 ON s1.barcode = s0.barcode
AND s1.stagename = 'printing'
AND s1.Description <> 'Success'
WHERE s0.stagename = 'molding'
AND s0.Description = = 'success'
This would be even better if you can know the date of the s1
record is older than for the s0
record, since I expect there's probably also some kind of in-process
stage that is also not a success.
Also, get rid of those (nolock)
hints. They probably are not accomplishing what you've been led to believe... at least, not in a safe way. (nolock)
can make a database faster by ignoring certain locks. This comes at the risk of reading stale data. The thing is, the performance is only improved in those situations when the risk of reading stale data is much higher. If there's no stale data, then there wouldn't be a lock to ignore.
答案2
得分: 0
您可以使用集合运算符
select
s.barcode
from Stages s
where s.clientID = 'AmericanExpress'
and s.stagename = 'printing'
and s.Description <> 'Success'
intersect
select
s.barcode
from Stages s
where s.clientID = 'AmericanExpress'
and s.stagename = 'Molding'
and s.Description = 'Success';
您还可以使用条件聚合
select
s.barcode
from Stages s
where s.clientID = 'AmericanExpress'
and s.stagename = 'printing'
group by
s.barcode
having count(case when s.stagename = 'Molding' and s.Description = 'Success' then 1 end) > 0
and count(case when s.stagename = 'printing' and s.Description <> 'Success' then 1 end) > 0;
英文:
You can use set operators
select
s.barcode
from Stages s
where s.clientID = 'AmericanExpress'
and s.stagename = 'printing'
and s.Description <> 'Success'
intersect
select
s.barcode
from Stages s
where s.clientID = 'AmericanExpress'
and s.stagename = 'Molding'
and s.Description = 'Success';
You can also use conditional aggregation
select
s.barcode
from Stages s
where s.clientID = 'AmericanExpress'
and s.stagename = 'printing'
group by
s.barcode
having count(case when s.stagename = 'Molding' and s.Description = 'Success' then 1 end) > 0
and count(case when s.stagename = 'printing' and s.Description <> 'Success' then 1 end) > 0;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论