SQL: как получить как совпадающие, так и не совпадающие записи - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть таблица со следующими полями.

  1. OrderId
  2. ItemId

В моей таблице есть следующие записи.

enter image description here

Я хочу сравнить оба OrderIds и получить результат, чтобы узнать, какие ItemIds существуют в обоих заказах, а какие нет.

Нужный мне результатниже.

enter image description here

ItemId: 200 существует в обоих заказах.

ItemId: 201 существует в 100, а не в 101

ItemId: 202 и 203 существуют в 101, а не в 100.

Я не уверен, что это можно сделать с помощью SQL.

Буду признателен за любую помощь.Заранее спасибо.

Сценарии SQL для тестирования:

Create table #Orders(OrderId INT, ItemId INT) Insert into #Orders Select 100, 200 Insert into #Orders Select 100, 201 Insert into #Orders Select 101, 200 Insert into #Orders Select 101, 202 Insert into #Orders Select 101, 203

Ответы [ 5 ]

0 голосов
/ 13 февраля 2019

Если вы хотите это только для двух заказов, вы можете сделать:

select coalesce(oi1.orderid, 100), coalesce(oi2.orderid, 101), oi1.itemid, oi2.itemid
from (select oi.*
      from orderitems oi
      where oi.orderid = 100
     ) oi1 full join
     (select oi.*
      from orderitems oi
      where oi.orderid = 101
     ) oi2
     on oi2.orderid <> oi1.orderid and
        oi2.itemid = oi1.itemid;

Здесь - это дБ <> скрипка.

Это отвечает на вопрос, которыйвы спрашивали.Если вы хотите обобщить это на большее количество заказов, пожалуйста, задайте еще один вопрос.Это обобщается не так легко, как вы думаете.

0 голосов
/ 13 февраля 2019

В одну сторону ...

DECLARE @O1 INT = 100, @O2 INT = 101;

SELECT FirstOrderID = @O1, 
       SecondOrderId = @O2, 
       FirstOrderItemId = MAX(CASE WHEN OrderId =@O1 THEN ItemId END), 
       SecondOrderItemId = MAX(CASE WHEN OrderId =@O2 THEN ItemId END)
FROM  #Orders 
WHERE OrderId IN (@O1, @O2)
GROUP BY ItemId 
0 голосов
/ 13 февраля 2019

Когда вы пишете: "Я хочу сравнить оба OrderIds и , чтобы получить результат, чтобы узнать, какие ItemIds существуют в обоих заказах , а какие нет."

Просто используйте INNER JOIN - результирующий набор будет включать все ItemIDs в обоих порядках:

      SELECT A.ItemID
        FROM dbo.yourtable A
  INNER JOIN dbo.yourtable B
          ON A.ItemID        = B.ItemID
         AND B.OrderID       = 101
       WHERE A.OrderID       = 100
0 голосов
/ 13 февраля 2019

Вам нужно сделать CROSS JOIN, а затем LEFT JOIN, чтобы проверить наличие.

Ваш желаемый результат не лучший для проверки этого, когда у вас есть несколько заказов и товаров, следующий выводдолжно быть достаточно хорошо:

;WITH AllOrders AS
(
    SELECT DISTINCT O.OrderID FROM #Orders AS O
),
AllItems AS
(
    SELECT DISTINCT O.ItemId FROM #Orders AS O
)
SELECT
    OrderId = O.OrderId,
    ItemId = I.ItemId,
    IsItemInOrder = CASE WHEN A.OrderId IS NOT NULL THEN 1 ELSE 0 END
FROM
    AllOrders AS O
    CROSS JOIN AllItems AS I
    LEFT JOIN #Orders AS A ON
        O.OrderId = A.OrderId AND
        I.ItemId = A.ItemId
ORDER BY
    O.OrderId,
    I.ItemId

Результаты:

OrderId ItemId  IsItemInOrder
100     200     1
100     201     1
100     202     0
100     203     0
101     200     1
101     201     0
101     202     1
101     203     1
0 голосов
/ 13 февраля 2019

Почему бы не использовать CROSS JOIN?

SELECT DISTINCT t.Orderid, tt.ItemID
FROM table t CROSS JOIN
     (SELECT DISTINCT ItemId FROM table t1) t1 LEFT OUTER JOIN
     table tt
     ON tt.Orderid = t.Orderid AND t1.Itemid = tt.ItemId;

Для достижения желаемого результата вам потребуется более динамичный подход, если вы сравните один или несколько ордеридов.Таким образом, CROSS JOIN было бы полезно в этом сценарии найти несоответствующие позиции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...