【问题标题】:SQL: Issue with WHERE on existing querySQL:现有查询的 WHERE 问题
【发布时间】:2021-11-03 20:46:27
【问题描述】:

下面的查询是提取每个 sku 的最大 exdt/seq 字段的记录。问题不是只从 WHERE 语句中提取项目 5343553,而是提取所有 5343553 的日期/序列相同的项目。所以在这种情况下,它会收集 100 多条不同项目的记录,这些记录等于 5343553 的最大日期 7/1,seq 2。

SELECT *  
FROM 
    (SELECT   
         item, cpp, exdt, seq, tv_1 + tf_1 AS tt_1
     FROM         
         dbo.sample123) t 
PIVOT 
    (SUM(tt_1) FOR cpp IN ([M], [LL], [OH] AS pvtc

WHERE     
    (exdt = (SELECT MAX(exdt) AS exdtmax
             FROM dbo.sample123 AS b
             WHERE (LTRIM(item) IN ('5343553'))) 
    AND (seq = (SELECT MAX(seq) AS seqmax
                FROM dbo.sample123 AS b
                WHERE (LTRIM(item) IN ('5343553')))))

所以我想的很简单,我将删除 WHERE,它应该给我所有 sku 及其最大日期/序列。下面反而返回空白,没有数据?

SELECT *  
FROM 
    (SELECT   
         item, cpp, exdt, seq, tv_1 + tf_1 AS tt_1
     FROM dbo.sample123) t 
PIVOT 
    (SUM(tt_1) FOR cpp IN ([M], [LL], [OH] AS pvtc

WHERE     
    (exdt = (SELECT MAX(exdt) AS exdtmax
             FROM dbo.sample123 AS b))
    AND (seq = (SELECT MAX(seq) AS seqmax
                FROM dbo.sample123 AS b))

我不确定我错过了什么。任何帮助将不胜感激!

谢谢。

【问题讨论】:

  • 格式正确的 SQL 更易于阅读和编写。
  • Microsoft SQL SMSS
  • 请提供minimal reproducible example,除了您的查询之外,还提供示例数据和所需结果。
  • 在子查询中使用别名:MAX(b.exdt)MAX(b.seq)
  • 我试过了,还是不行。

标签: sql sql-server tsql where-clause


【解决方案1】:

如果我正确理解了这个问题,并且您的第一个查询的问题是它不是“仅拿起项目 5343553”,那么我建议

WITH mycte AS
(
 SELECT *
 FROM dbo.sample123
 WHERE LTRIM(item) IN ('5343553')
)
SELECT *  
FROM 
    (SELECT   
         item, cpp, exdt, seq, tv_1 + tf_1 AS tt_1
     FROM         
         mycte) t 
PIVOT 
    (SUM(tt_1) FOR cpp IN ([M], [LL], [OH] AS pvtc 
WHERE     
    (exdt = (SELECT MAX(exdt) AS exdtmax
             FROM mycte) 
    AND (seq = (SELECT MAX(seq) AS seqmax
                FROM mycte))

这使您的所有子查询都应用该条件。 (您可以将条件放在所有子查询中,但 CTE 意味着您只需要编写一次。)

根据下面的 cmets,我怀疑您真正想要的是以下内容,它返回所有数据,但仅返回最大值与该项目匹配的行。请注意,我使用LTRIM(t2.item)=LTRIM(t.item)(而不仅仅是t2.item=t.item)与您在WHERE 条件下的操作方式保持一致。

SELECT *  
FROM 
    (SELECT   
         item, cpp, exdt, seq, tv_1 + tf_1 AS tt_1
     FROM         
         dbo.sample123) t 
PIVOT 
    (SUM(tt_1) FOR cpp IN ([M], [LL], [OH] AS pvtc 
WHERE     
    exdt = (SELECT MAX(exdt) AS exdtmax
             FROM dbo.sample123 t2
             WHERE LTRIM(pvtc.item)=LTRIM(t.item)) 
    AND seq = (SELECT MAX(seq) AS seqmax
                FROM dbo.sample123 t2
                WHERE LTRIM(pvtc.item)=LTRIM(t.item))

还有一个可能更简洁的例子:

SELECT *  
FROM 
    (SELECT   
         item, cpp, exdt, seq, tv_1 + tf_1 AS tt_1
     FROM         
         dbo.sample123 t
     WHERE
         exdt = (SELECT MAX(exdt) AS exdtmax
             FROM dbo.sample123 t2
             WHERE LTRIM(t2.item)=LTRIM(t.item)) 
         AND seq = (SELECT MAX(seq) AS seqmax
                FROM dbo.sample123 t2
                WHERE LTRIM(t2.item)=LTRIM(t.item))) t 
PIVOT 
    (SUM(tt_1) FOR cpp IN ([M], [LL], [OH] AS pvtc 

【讨论】:

  • 效果很好。我唯一的问题是,如果我在您添加的 mycte 部分中删除 WHERE LTRIM(item) in ('5343553') 条件,我希望它会拉出所有 skus。相反,它是没有数据的空白。
  • 我认为这是正确的......可能没有行匹配最大 exdt 和最大 seq。 (例如,如果 item2 的最大 exdt 是 2099-01-01,而 item3 的最大 seq 是 100,则可能没有行匹配两者)。如果您发布了一些实际数据和您期望的结果,这将很有用,但我会编辑我的回复并猜测您正在尝试做什么。
  • 成功了,谢谢。我不得不在 WHERE 中将 t.item 调整为 pvtc.item,基本上是参考枢轴。我得到了一个无法绑定的错误。我认为这是我困惑的一部分,因为这是我的第一个 PIVOT 函数。谢谢。
  • 啊,对,我的错。我将修复示例。将条件移动到子查询中可能会降低此错误的可能性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多