Выберите строки с тем же кодом товара, но с другим значением в другом столбце

У меня есть данные из двух таблиц. Элемент и местоположение взяты из таблицы A, а описание из таблицы B. Я пытаюсь написать Oracle SQL, где я могу получить те элементы и местоположения, описание которых в блоке 1 отличается от всех других блоков для того же элемента, но покажите мне только строки с Loc 1 и Loc 2.

Я попытался получить полный список, а затем экспортировать его в Excel, а затем найти дубликаты и т. д., но этот список настолько длинный, что экспорт fn не работает, а также копирование и вставка в Excel.

Конечная цель здесь заключается в том, что мне нужно обновить описание Loc 1 тем, что есть в строках Loc 2.

Итак, вот чего я стремлюсь достичь с помощью этого SQL.

Пожалуйста, отредактируйте вопрос, включив в него минимальный воспроизводимый пример с утверждениями CREATE TABLE и INSERT для вашего образца данных (текст, который мы можем скопировать, вставить и выполнить, а не изображения). На данный момент, судя по вашему описанию, между двумя таблицами не существует никаких ссылочных ограничений, если таблица A содержит только два столбца item и location, а таблица B содержит только один столбец description, поэтому нет возможности соединить две таблицы. ; вам нужно иметь первичный ключ, а затем присоединиться на его основе.

MT0 28.06.2024 15:13

Спасибо МТО. Я отредактирую таблицы, как вы предложили, как только научусь это делать. Что касается самого SQL, спасибо за ваш вклад, но есть два замечания. Обе таблицы объединены еще одним столбцом, назовем его «Item_Identifier», общим для них обоих, который равен 1-1, поэтому я присоединил их по этому поводу. Однако когда я запускаю SQL, я получаю ошибку, указывающую на самую последнюю строку кода. ORA-00904: «LOCATION»: неверный идентификатор 00904. 00000 — «%s: неверный идентификатор» *Причина: *Действие:

redoctober 28.06.2024 16:33

................COUNT(ОТЛИЧНОЕ описание) OVER (РАЗДЕЛЕНИЕ ПО элементу) AS num_descr FROM ItemTable A соединить ItemDescriptionTable B с A.Item_Identifier = B. Item_Identifier ) WHERE num_descr = 2.. ........

redoctober 28.06.2024 16:39

Привет, MTO! Да, у меня это тоже сработало. Конечно, мне пришлось немного подправить код, но да, это сработало. Все три приведенных ниже SQL-кода представляли собой разные подходы, но я заставил работать и ваш. Спасибо за вашу помощь и усилия.

redoctober 02.07.2024 12:02
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
4
84
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы можете использовать условную агрегацию с аналитическими функциями:

SELECT item,
       location,
       description
FROM   (
  SELECT item,
         location,
         description,
         COUNT(DISTINCT CASE location WHEN 'Loc 1' THEN description ELSE NULL END) OVER (
           PARTITION BY item
         ) AS num_loc1,
         COUNT(DISTINCT CASE location WHEN 'Loc 1' THEN NULL ELSE description END) OVER (
           PARTITION BY item
         ) AS num_other_loc,
         COUNT(DISTINCT description) OVER (PARTITION BY item) AS num_descr
  FROM   a
         INNER JOIN b
         ON a.item_id = b.item_id
)
WHERE  num_descr > 1
AND    num_loc1 = 1
AND    num_other_loc + num_loc1 = num_descr
AND    location IN ('Loc 1', 'Loc 2')

или, в зависимости от того, как вы хотите реализовать логику «где описание в Loc 1 отличается от всех других Locs для того же элемента», вы можете изменить окончательный фильтр на:

WHERE  num_descr > 1
AND    num_loc1 = 1
AND    num_other_loc + num_loc1 = num_descr
AND    location IN ('Loc 1', 'Loc 2')

Что для примера данных:

CREATE TABLE a (item_id, item, location) AS
SELECT  1, 'Item A', 'Loc 1' FROM DUAL UNION ALL
SELECT  2, 'Item A', 'Loc 2' FROM DUAL UNION ALL
SELECT  3, 'Item A', 'Loc 3' FROM DUAL UNION ALL
SELECT  4, 'Item A', 'Loc 4' FROM DUAL UNION ALL
SELECT  5, 'Item B', 'Loc 1' FROM DUAL UNION ALL
SELECT  6, 'Item B', 'Loc 2' FROM DUAL UNION ALL
SELECT  7, 'Item B', 'Loc 3' FROM DUAL UNION ALL
SELECT  8, 'Item B', 'Loc 4' FROM DUAL UNION ALL
SELECT  9, 'Item C', 'Loc 1' FROM DUAL UNION ALL
SELECT 10, 'Item C', 'Loc 2' FROM DUAL UNION ALL
SELECT 11, 'Item C', 'Loc 3' FROM DUAL UNION ALL
SELECT 12, 'Item C', 'Loc 4' FROM DUAL;

CREATE TABLE b (item_id, description) AS
SELECT 1, 'Tube' FROM DUAL UNION ALL
SELECT 2, 'Pipe' FROM DUAL UNION ALL
SELECT 3, 'Pipe' FROM DUAL UNION ALL
SELECT 4, 'Pipe' FROM DUAL UNION ALL
SELECT 5, 'Mallet' FROM DUAL UNION ALL
SELECT 6, 'Mallet' FROM DUAL UNION ALL
SELECT 7, 'Mallet' FROM DUAL UNION ALL
SELECT 8, 'Mallet' FROM DUAL UNION ALL
SELECT 9, 'Wrench' FROM DUAL UNION ALL
SELECT 10, 'Spanner' FROM DUAL UNION ALL
SELECT 11, 'Spanner' FROM DUAL UNION ALL
SELECT 12, 'Spanner' FROM DUAL;

Оба вывода:

ЭЛЕМЕНТ РАСПОЛОЖЕНИЕ ОПИСАНИЕ Пункт А Лок 1 Трубка Пункт А Лок 2 Трубка Пункт С Лок 1 Гаечный ключ Пункт С Лок 2 Гаечный ключ

рабочий пример

Другой способ решить эту проблему — использовать оператор case и оператор существования. но вам также нужен уникальный идентификатор двух таблиц (a, b)

with all_data as (
select a.*, b.description from a join b on a.item_id=b.item_id
), flag as (
select a.* , case when exists ( 
                               select * from all_data where item=a.item and a.location <location and a.description <> description)
                                                                                                             
              then 1 else 0 end as flag
from all_data a
), grp as (
select a.*, sum(flag)over(partition by item order by location)as grp, 
            row_number()over(partition by item order by location)as rn_loc
from flag a 
)
select item, location, description
from grp
where grp=1 and rn_loc<3;

Надеюсь, поможет.

Спасибо Флорин. Я опробую ваши предложения в ближайшие пару дней и оставлю отзывы.

redoctober 01.07.2024 17:31

Пожалуйста, сделайте это. Спасибо.

Florin 01.07.2024 21:55

Привет Флорин. Да, мне это помогло. Конечно, мне пришлось немного подправить код, но да, это сработало. Спасибо. То же самое и с двумя другими предложениями. Еще раз спасибо.

redoctober 02.07.2024 12:00

Если у вас уже есть запрос, результат которого такой же, как в начале вопроса...

-- lets imagine this is your query
      Select      A.ITEM, A.LOCATION, B.DESCRIPTION
      From        A
      Inner Join  B ON ( /* your join condition(s) */ )
      Order By    A.ITEM, A.LOCATION
/*
ITEM    LOCATION    DESCRIPTION
------  ----------  -------------
Item A  Loc 1       Tube
Item A  Loc 2       Pipe
Item A  Loc 3       Pipe
Item A  Loc 4       Pipe
Item B  Loc 1       Mallet
Item B  Loc 2       Mallet
Item B  Loc 3       Mallet
Item B  Loc 4       Mallet
Item C  Loc 1       Wrench
Item C  Loc 2       Spanner
Item C  Loc 3       Spanner
Item C  Loc 4       Spanner
Item C  Loc 5       Spanner
Item C  Loc 6       Spanner
Item C  Loc 7       Spanner       */

... тогда вы могли бы объявить его sql как cte (назвав его all_data) и, используя только этот cte, получить результат...

WITH
  all_data AS      -- Your query's sql declared as cte named all_data
    ( Select      A.ITEM, A.LOCATION, B.DESCRIPTION
      From        A
      Inner Join  B ON ( /* your join condition(s) */ )
      Order By    A.ITEM, A.LOCATION
   )
--    M a i n    S Q L :
Select      a.ITEM, a.LOCATION, a.DESCRIPTION 
From        all_data a
Inner Join  ( Select  ITEM, DESCRIPTION
              From all_data
              Group By  ITEM, DESCRIPTION
              Having    Count(Distinct LOCATION) = 1 
            ) g ON( ( g.ITEM = a.ITEM And g.DESCRIPTION = a.DESCRIPTION And a.LOCATION = 'Loc 1') 
                      OR
                       ( g.ITEM = a.ITEM And g.DESCRIPTION != a.DESCRIPTION And a.LOCATION = 'Loc 2') 
                    )

... подзапрос в основном sql будет извлекать только элементы, имеющие уникальное описание Loc 1 для каждого элемента, а условия включения соединения должны фильтровать конечный результат, который должен быть...

/*    R e s u l t :
ITEM    LOCATION    DESCRIPTION
------  ----------  -------------
Item A  Loc 1       Tube
Item A  Loc 2       Pipe
Item C  Loc 1       Wrench
Item C  Loc 2       Spanner    */

Спасибо, д р. Я опробую ваши предложения в ближайшие пару дней и оставлю отзывы.

redoctober 01.07.2024 17:30

Привет, доктор, Да, это сработало и для меня. Конечно, мне пришлось немного подправить код, но да, это сработало. Спасибо

redoctober 02.07.2024 12:01

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

d r 02.07.2024 13:30

Сделанный. Еще раз спасибо, доктор. Цените помощь и усилия.

redoctober 02.07.2024 17:07

@redoctober Хороший выбор, спасибо.

d r 02.07.2024 19:21

Другие вопросы по теме

Похожие вопросы