可以使用CTE来处理存在于一个表中的数据,而不是两个吗?

huangapple go评论56阅读模式
英文:

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 = &#39;printing&#39;
    AND s1.Description &lt;&gt; &#39;Success&#39;
WHERE s0.stagename = &#39;molding&#39;
    AND s0.Description = = &#39;success&#39;

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 = &#39;AmericanExpress&#39;
  and s.stagename = &#39;printing&#39;
  and s.Description &lt;&gt; &#39;Success&#39;

intersect

select
  s.barcode
from Stages s
where s.clientID = &#39;AmericanExpress&#39;
  and s.stagename = &#39;Molding&#39;
  and s.Description = &#39;Success&#39;;

You can also use conditional aggregation

select
  s.barcode
from Stages s
where s.clientID = &#39;AmericanExpress&#39;
  and s.stagename = &#39;printing&#39;
group by
  s.barcode
having count(case when s.stagename = &#39;Molding&#39;  and s.Description =  &#39;Success&#39; then 1 end) &gt; 0
   and count(case when s.stagename = &#39;printing&#39; and s.Description &lt;&gt; &#39;Success&#39; then 1 end) &gt; 0;

huangapple
  • 本文由 发表于 2023年6月13日 01:33:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76459025.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定