SQL -объединение двух таблиц или генерация последовательности в столбце

#sql #sql-server #tsql

#sql #sql-сервер #tsql

Вопрос:

У меня есть 2 таблицы, Table1 получил OrderNo и OrderItemId, Table2 получил OrderNo и Linenum. Мне нужно создать временную таблицу, которая показывает orderno, orderItemid и Linenum. Как я могу добиться желаемого результата? Если объединение невозможно, то мы можем сгенерировать последовательность также для номера OrderItemId против Order. Предположим, что заказ получил 5 OrderItemId, тогда мы можем иметь серии от 1 до 5, а следующий заказ будет иметь серии, начинающиеся с 1 до общего количества связанных Orderitemid.

Я попробовал это, но серия генерируется неправильно. Это не по порядку

 Select Orderitemid, table1.OrderNo,  
SELECT ROW_NUMBER() OVER(ORDER BY table2.ORDERNO ASC)*1000 AS Linenum 
from Table1 inner join Table2
on table1.Orderno = table2.Orderno
 

введите описание изображения здесь

Комментарии:

1. В таблице 1 и таблице 2, если мы добавим столбец цены и хотим отобразить его вместе с другим столбцом. Просто хотел убедиться, что цена заказа в обеих таблицах совпадает. Любое предложение по этому поводу.

Ответ №1:

Может быть, что-то вроде этого было бы тем, что вы ищете:

 select table1.OrderNo
       , table1.Orderitemid
       , ROW_NUMBER() OVER(partition by table1.OrderNo ORDER BY table1.ORDERNO ASC) AS Linenum 
from Table1 
left join Table2 on table1.OrderNo = table2.OrderNo
group by table1.OrderNo, table1.Orderitemid
 

Вы можете выполнить группировку только для таблицы2:

 select table1.OrderNo
       , table1.Orderitemid
       , ROW_NUMBER() OVER(partition by table1.OrderNo ORDER BY table1.ORDERNO ASC) AS Linenum 
from Table1 
left join (select OrderNo 
           from Table2 
           group by OrderNo) table2 on table1.OrderNo = table2.OrderNo
 

Или просто используйте distinct:

 select table1.OrderNo
       , table1.Orderitemid
       , ROW_NUMBER() OVER(partition by table1.OrderNo ORDER BY table1.ORDERNO ASC) AS Linenum 
from Table1 
left join (select distinct OrderNo 
           from Table2 ) table2 on table1.OrderNo = table2.OrderNo
 

Или, если вы не хотите генерировать Linenum, если в table2 нет соединения, вы можете добавить case when then else end

 select table1.OrderNo
       , table1.Orderitemid
       , case when table2.OrderNo is not null then
                  ROW_NUMBER() OVER(partition by table1.OrderNo ORDER BY table1.ORDERNO ASC)
              else
                  null
              end Linenum
from Table1 
left join (select distinct OrderNo 
           from Table2 ) table2 on table1.OrderNo = table2.OrderNo
 

Вот демонстрация:

ДЕМОНСТРАЦИЯ

Комментарии:

1. Добро пожаловать, я рад помочь. Приветствия!

2. Единственная проблема, теперь, если Orderno отсутствует в таблице 2, он не должен генерировать последовательность. Но это так . Если я использую case, как предложил Гордон, тогда group by выдает ошибку

3. Вы не хотите получать результаты для 3000 в вашем примере?

4. @Sbanga пожалуйста, проверьте последний запрос здесь: dbfiddle.uk /…

5. Прошу прощения за ошибку, я открываю страницу, чтобы написать еще несколько запросов

Ответ №2:

Я думаю, вам просто нужно case выражение:

 Select Orderitemid, table1.OrderNo,
       (case when t2 is not null
             then row_number() over (partition by t1.orderno order by t1.orderitemid)
        end) as linenum
from Table1 t1 left join
     (select distinct t2.orderno
      from Table2 t2
     ) t2
     on t1.Orderno = t2.Orderno;
 

То есть вам просто нужны номера строк, когда есть совпадение во второй таблице.

Комментарии:

1. Это дает мне результат в Кристиане . Где он должен показывать только 2 строки, но он показывает 4 OrderNo OrderItemId LineNum 1000 101 1 1000 101 2 1000 102 1 1000 102 2

2. @Sbanga . , , я пропустил, что у вас есть дубликаты во второй таблице. Я обновил ответ.