СОЮЗ имеет квазидубликаты. Как выбрать только из одной таблицы - PullRequest
0 голосов
/ 30 октября 2019

2 таблицы: яблоки и апельсины. Каждый из них имеет одинаковую структуру - 2 столбца: Продукт и Цена.

Думая о ней как о диаграмме Венна в 3 примерно равных частях. Таким образом, яблоки и апельсины имеют примерно одну треть данных - по крайней мере, на уровне продукта. Есть небольшое количество записей, в которых названия Продуктов одинаковы, но Цены разные, поэтому они естественным образом проскальзывают через UNION и создают для этих Продуктов 2 строки.

Теперь мне просто интересно, как изменитьзапрос UNION, так что в тех случаях, когда Продукт такой же, но Цены разные, он просто использует Apples.Price в качестве единственной цены.

Будет использовать этот UNION для присоединения к другой таблице, т.е.

WITH CTE AS
    (
        SELECT * FROM #Apples
        UNION
        SELECT * FROM #Oranges
    )
SELECT * FROM CTE c INNER JOIN Map m
    ON c.Product = m.Product

Примеры результатов объединения:

|---------------------|------------------|
|       PRODUCT       |      PRICE       |
|---------------------|------------------|
|        Jeans        |       50         | --from Apples
|---------------------|------------------|
|        Car          |       7500       | --from Oranges
|---------------------|------------------|
|        Phone        |       600        | --from Apples
|---------------------|------------------|
|        Phone        |       625        | --from Oranges

В идеале нужно всего 3 строки, в которых возвращается значение «Телефон на 600».

Ответы [ 2 ]

3 голосов
/ 30 октября 2019

Поскольку вы возвращаете все из обеих таблиц, вы можете просто использовать OUTER JOIN:

WITH CTE AS
    (
        SELECT 
            ISNULL(Apples.Product, Oranges.Product) AS Product,
            ISNULL(Apples.Price, Oranges.Price) AS Price
        FROM #Apples AS Apples
        FULL OUTER JOIN #Oranges AS Oranges
            ON Apples.Product = Oranges.Product        
    )
SELECT * FROM CTE c INNER JOIN Map m
    ON c.Product = m.Product

. При этом будут выбраны все значения из #Apples и #Oranges, но если есть перекрывающиеся продукты, тоон выберет цену от #Apples до #Oranges. ISNULL гарантирует, что мы получим что-то обратно для каждого столбца в «объединении», которое мы делаем. Обратите внимание, что если столбец Product не уникален в каждой таблице, вы можете получить дубликаты в результате.

2 голосов
/ 30 октября 2019

Вы можете исключить перекрывающиеся продукты из результатов Oranges с помощью WHERE NOT EXISTS.

WITH cte
  AS
  (
    SELECT * FROM @apples AS a
    UNION
    SELECT * FROM @oranges AS o
    WHERE
      NOT EXISTS
      (
        SELECT 1 
        FROM @apples AS a1  
        WHERE a1.product = o.product
      )
  )
SELECT
  *
FROM
  cte;
+---------+-------+
| product | price |
+---------+-------+
| car     |  7500 |
| jeans   |    50 |
| phone   |   625 |
+---------+-------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...