【问题标题】:SQL Server: only return data if count of one column is greater than anotherSQL Server:仅当一列的计数大于另一列时才返回数据
【发布时间】:2016-03-08 17:45:33
【问题描述】:

我想做什么:

如果表OITMOITM.AssetSerNo)中某个序列号的出现总数大于RDN1RDN1.SerialNum)中相同序列号的出现总数,那么我想从OITM 记录中返回一些字段,其中资产编号OITM.ItemCode (PKey) 最大。

我的代码如下

select 

oitm.itemcode as 'Asset No', 
oitm.itemname as 'Asset Description',
oitm.assetSerNo as 'Serial No'

from oitm
inner join rdn1 on oitm.assetserno = rdn1.serialnum

WHERE
OITM.itemtype = 'F'
and OITM.asststatus = 'A'

HAVING count(oitm.assetserno)>count(rdn1.serialnum)

很遗憾,我收到错误消息,因为我的大多数项目既不在 group by 也不在聚合函数中。我什至不确定HAVING 子句是解决问题的最佳方法(事实上,我很确定它不是)。

编辑:样本数据(我猜?)

OIT

ItemCode ItemName AssetSerNo ItemType AsstStatus
123 对象 1 QW F I
234 对象 2 ER F A
345 对象 3 RT F I
456 对象 4 TY F A
567 对象 1 QW F I
第678章 对象5
789 对象 3 RT F A
890 对象 1 QW F A
901 对象 2 UI F A

这是一个物料主清单数据记录。 A = 有效,I = 无效。

RDN1

DocID 对象名称 序列号
1 个对象 1 个 QW
2 对象 3 RT
3 对象 1 QW
4 对象 5 YU
5 对象 4 TY
6 对象 3 RT

这是一个退货记录列表,用于租用物品何时返回仓库。

预期输出:

ItemCode ItemName AssetSerNo
789 对象 3 RT
456 对象 4 TY

我需要一份已创建退货但尚未停用的所有商品的列表。我不能只在 RDN1 上进行内部联接,因为我可能有返回的项目,项目记录更改为 I,但随后它被送回并创建了一个新的项目记录。

【问题讨论】:

  • 发布样本数据和预期输出。
  • 这就是问题所在。我没有任何样本数据。我基本上在这里工作是盲目的。不过,我会尝试模拟一些。

标签: sql sql-server


【解决方案1】:

20 种不同的方法可以做到这一点,它们都很好。这是使用大部分代码并实现 EXISTS() 命令的方式。

select 
 oitm.itemcode as 'Asset No', 
 oitm.itemname as 'Asset Description',
 oitm.assetSerNo as 'Serial No'
from oitm x
WHERE
 EXISTS(
  select TOP 1 1 
  from oitm y
   inner join rdn1 z on y.assetserno = z.serialnum
  WHERE
   y.itemtype = 'F'
   and y.asststatus = 'A'
   and y.assetSerNo = x.assetSerNo 
  HAVING count(y.assetserno)>count(z.serialnum)
)

【讨论】:

  • 谢谢,史蒂夫!我已经稍微更新了这个问题(并将添加更多内容)。我是 SQL 新手,不熟悉 EXISTS 标签。如果我还要从另一个表中提取其他信息,我是否会将其放在相同的 SelectFrom 开头,在 WHEREEXISTS 之前?你能告诉我你给我的查询是否应该像我在问题中那样给出输出?
  • 关键,通过使用 xyz 表命名稍微隐藏,是末尾的 y.assetSerNo = x.assetSerNo 。这是从exists() 命令中使用的子选择获取记录,仅用于外部选择。您可以使用IN() 命令或多个嵌套选择,它们都会同时返回相同的内容(很有可能)。是的,如果您需要更多列,请将它们添加到顶部选择中。这是你的输出。
【解决方案2】:

这是一个使用一些子查询的选项

SELECT 
    item.itemcode AS 'Asset No',
    item.itemname AS 'Asset Description',
    item.assetSerNo AS 'Serial No'
FROM
(
    SELECT
        oitm.itemcode,
        oitm.itemname,
        oitm.assetSerNo,
        COUNT() OVER (PARTITION BY assetSerNo) assetSerNoCount,
        ROW_NUMBER() OVER (PARTITION BY assetSerNo ORDER BY oitm.itemcode DESC) rn
    FROM
        oitm
    WHERE
        OITM.itemtype = 'F'
        AND OITM.asststatus = 'A'
) item
LEFT JOIN (
    SELECT 
        serialnum, COUNT(*) serialnumCount 
    FROM 
        rdn1 
    GROUP BY 
    serialnum
) serial ON serial.serialnum = item.assetSerNo
WHERE
    ISNULL(serial.serialnumCount,0) < item.assetSerNoCount
    AND item.rn = 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    • 2015-02-21
    • 2019-08-07
    • 1970-01-01
    相关资源
    最近更新 更多