按主键的行数过滤

时间:2017-05-22 19:32:07

标签: sql sql-server

我有一个查询,有时会返回不需要的行。

SELECT TOP 100 PERCENT 
    ca.item_id, ca.FIELD_ID, ca.attr_val, ca.upd_dtt, ca.upd_usr
FROM 
    contract_attr ca
WHERE 
    EXISTS (SELECT 1
            FROM contract_attr ca_326
            WHERE ca.item_id = ca_326.item_id
              AND ca_326.field_id = 326
              AND ca_326.ATTR_VAL = 'Y')

UNION ALL

SELECT 
    ca.item_id, 9999, mf.[ITEM_NAME], '', ''
FROM 
    mfr mf
JOIN 
    contract_attr ca ON ca.attr_val = mf.[ITEM_PK]
ORDER BY 
    ca.item_id

enter image description here

item_id在图像上的10-13只有1行。

我想从查询中过滤这些行。看起来我应该添加一个:

SELECT TOP 100 PERCENT 
    ca.item_id, ca.FIELD_ID, ca.attr_val, ca.upd_dtt, ca.upd_usr
FROM 
    contract_attr ca
WHERE 
    EXISTS (SELECT 1
            FROM contract_attr ca_326
            WHERE ca.item_id = ca_326.item_id
              AND ca_326.field_id = 326
              AND ca_326.ATTR_VAL = 'Y')

UNION ALL

SELECT 
    ca.item_id, 9999, mf.[ITEM_NAME], '', ''
FROM 
    mfr mf
JOIN 
    contract_attr ca ON ca.attr_val = mf.[ITEM_PK]
HAVING 
    COUNT(ca.item_id) > 1
ORDER BY 
    ca.item_id

但我收到此错误并且不明白原因:

  

列'contract_attr.ITEM_ID'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

我做错了什么以及如何解决?

2 个答案:

答案 0 :(得分:3)

由于您希望返回多个列,这些列无法通过拥有所需的分组来完成,因此您可以在子查询中使用。

SELECT TOP 100 PERCENT 
    ca.item_id
    ,ca.FIELD_ID
    ,ca.attr_val
    ,ca.upd_dtt
    ,ca.upd_usr
FROM contract_attr ca
            WHERE EXISTS (
        SELECT 1
        FROM contract_attr ca_326
        WHERE ca.item_id = ca_326.item_id
            AND ca_326.field_id = 326
            AND ca_326.ATTR_VAL = 'Y'
        )
UNION ALL
SELECT ca.item_id
    ,9999
    ,mf.[ITEM_NAME]
    ,''
    ,''
FROM mfr mf
JOIN contract_attr ca ON ca.attr_val = mf.[ITEM_PK]
INNER JOIN(SELECT item_id FROM contract_attr group by item_id having count(item_id) > 1) x on x.item_id = ca.item_id
ORDER BY ca.item_id

答案 1 :(得分:2)

您错过了group by

SELECT TOP 100 PERCENT ca.item_id
        ,ca.FIELD_ID
        ,ca.attr_val
        ,ca.upd_dtt
        ,ca.upd_usr
    FROM contract_attr ca
                WHERE EXISTS (
            SELECT 1
            FROM contract_attr ca_326
            WHERE ca.item_id = ca_326.item_id
                AND ca_326.field_id = 326
                AND ca_326.ATTR_VAL = 'Y'
            )
    UNION ALL
    SELECT ca.item_id
        ,9999
        ,mf.[ITEM_NAME]
        ,''
        ,''
    FROM mfr mf
    JOIN contract_attr ca ON ca.attr_val = mf.[ITEM_PK]
    group by ca.item_id, mf.[ITEM_NAME]
    HAVING count(ca.item_id) > 1
    ORDER BY ca.item_id