使用SQL选择列1中具有相同值但列2和3中具有不同值的所有行

时间:2018-08-11 07:55:16

标签: sql sql-server tsql

我有一个看起来像这样的桌子

enter image description here

每个[订单号]可以具有1个或多个[行号],每个[行号]的状态都可以为[已发货]或[未发货]。

我想选择包含[行号]同时具有[已发货]和[未发货]的所有[订单号]。

例如,这些[订单号]包含[行号]以及[运费]和[取消运费]同时显示,因此应该选择

enter image description here

这是我的查询,但没有返回正确的结果

SELECT [Order number], [Line number], [SHIPPED/UNSHIPPED] 
FROM [mytable]
WHERE [Order number] IN (SELECT [Order number]
                         FROM [mytable]
                         GROUP BY [Order number]
                         HAVING COUNT(*) > 1)
ORDER BY [Order number], [Line number]

任何建议,请问我的查询中缺少什么?谢谢。

5 个答案:

答案 0 :(得分:4)

这是一种方法:

WITH cte AS (
    SELECT [Order number]
    FROM mytable
    WHERE [SHIPPED/UNSHIPPED] IN ('SHIPPED', 'UNSHIPPED')
    GROUP BY [Order number]
    HAVING COUNT(DISTINCT [SHIPPED/UNSHIPPED]) = 2
)

SELECT *
FROM mytable
WHERE [Order number] IN (SELECT [Order number] FROM cte);

CTE查找所有已发货和未发货记录的订单号。它的工作方式是首先将给定订单的记录限制为仅已装运/未装运的记录,然后断言该组的不同数量为2,这意味着同时存在两种类型的装运。

答案 1 :(得分:1)

您的查询几乎是正确的,只是我需要做一些更改

    SELECT [Order number],[Line number],[SHIPPED/UNSHIPPED] FROM [mytable]
    WHERE [Order number] IN (
    SELECT [Order number]
    FROM [mytable]
    WHERE [SHIPPED/UNSHIPPED] IN ('SHIPPED', 'UNSHIPPED') --added where clause
    GROUP BY [Order number]
    HAVING COUNT(DISTINCT [SHIPPED/UNSHIPPED]) >= 2 --changed this condition
    )
    ORDER BY [Order number],[Line number]

答案 2 :(得分:1)

与其他答案相反,我认为您的意思是[行号]必须同时具有两种状态:

OrderNumber LineNumber UNSHIPPED/SHIPPED
1           20         SHIPPED
1           20         UNSHIPPED
2           30         SHIPPEd
2           40         UNSHIPPED

然后,所需的重用将仅为[Order number] = 1,因为它同时具有两种状态。

根据此逻辑,这里是查询:

SELECT OrderNumber,
       LineNumber,
       [Unshipped/Shipped]
FROM (
    SELECT OrderNumber,
           LineNumber,
           [Unshipped/Shipped],
           COUNT(DISTINCT [Unshipped/Shipped]) OVER (PARTITION BY OrderNumber, LineNumber) cnt
    FROM my_table
    WHERE [Unshipped/Shipped] IS NOT NULL
) a WHERE cnt > 1

或使用GROUP BY

SELECT OrderNumber,
       LineNumber
FROM my_table
WHERE [Unshipped/Shipped] IS NOT NULL
GROUP BY OrderNumber, LineNumber
HAVING COUNT(DISTINCT [Unshipped/Shipped]) > 1

答案 3 :(得分:1)

另一个

with
    shipped as (select distinct [Order number] from mytable where [SHIPPED/UNSHIPPED] = 'SHIPPED'),
    unshipped as (select distinct [Order number] from mytable where [SHIPPED/UNSHIPPED] = 'UNSHIPPED'),
    both as (select [Order number] from shipped intersect select [Order number] from unshipped)

select * from mytable where [Order number] in (select [Order number] from both)

答案 4 :(得分:1)

  

我想选择包含[行号]同时具有[已发货]和[未发货]的所有[订单号]。

您的问题专门仅询问订单,因此结果集每个订单应有一行。我通常会使用聚合来解决这个问题:

select [Order number]
from mytable
where [SHIPPED/UNSHIPPED] in ('SHIPPED', 'UNSHIPPED')
group by [Order number]
having min([SHIPPED/UNSHIPPED]) <> max([SHIPPED/UNSHIPPED]);

另一种聪明的方法使用intersect

select [Order number]
from mytable
where [SHIPPED/UNSHIPPED] = 'SHIPPED'
intersect
select [Order number]
from mytable
where [SHIPPED/UNSHIPPED] = 'UNSHIPPED';

如果您确实需要行号,请将JOIN / IN / EXISTS与上面的内容一起用作子查询。另一种方法是使用窗口函数。