WedX - журнал о программировании и компьютерных науках

Как реализовать ZIP JOIN в T-SQL?

Допустим, у меня есть таблица #Foo:

Id Color
-- ----
1  Red
2  Green
3  Blue
4  NULL

И стол #Бар:

Value
-----
1
2.5

Я хотел бы создать таблицу Result, используя простой оператор, чтобы получить:

Id Color   Value
-- ----   -----
1  Red    1
2  Green  2.5
3  Blue   NULL
4  NULL   NULL

То, что я изобрел до сих пор, это:

WITH cte1
AS
(
    SELECT [Id], [Color], ROW_NUMBER() OVER (ORDER BY [Id]) AS 'No'
    FROM #Foo
),
cte2
AS
(
    SELECT [Value], ROW_NUMBER() OVER (ORDER BY [Value]) AS 'No'
    FROM #Bar
)
SELECT [Id], [Color], [Value]
FROM cte1 c1
FULL OUTER JOIN cte2 c2 ON c1.[No] = c2.[No]

Знаете ли вы более быстрый или более стандартный способ сделать ZIP JOIN в T-SQL?

17.06.2014

  • Ваше решение - это то, как я должен был это сделать. 17.06.2014
  • ZIP JOIN? Что это? 17.06.2014
  • @ypercube stackoverflow.com/a/17581681/2042090 17.06.2014
  • Это похоже на соединение с довольно узкой применимостью из-за реляционной модели, требующей, чтобы порядок строк, как правило, не имел значения для отношений. Я не ожидал, что вы найдете что-нибудь быстрее. Если вам нужна производительность, вероятно, будет быстрее сгенерировать два упорядоченных набора результатов из двух запросов, а затем обработать соединение в вашем приложении, прокручивая результаты. 23.01.2015

Ответы:


1

Вы можете просто попробовать это.

;WITH CTE AS
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS Id, Value FROM #Bar
)
SELECT F.Id, F.Color, CTE.Value
FROM #Foo F
LEFT JOIN CTE ON CTE.Id = F.Id
03.12.2017

2

Вы можете избавиться от the CTE или сделать свой query shorter

с таким подзапросом

select Id,Color,Value from 
(
    SELECT [Id], [Color], ROW_NUMBER() OVER (ORDER BY [Id]) AS 'No'
    FROM #Foo
)x full outer join 
(
    SELECT [Value], ROW_NUMBER() OVER (ORDER BY [Value]) AS 'No'
    FROM #Bar
)y
on x.No=y.No
17.06.2014
  • Это более оптимизировано, потому что вы изменили тип соединения. CTE всегда встраиваются оптимизатором запросов, как вы это делали вручную. 17.06.2014
  • Однако им нужно FULL присоединиться, а не LEFT. 17.06.2014
  • упс!! да они оба одинаковые! может это короче? 17.06.2014
  • Я считаю, что я большой поклонник версии CTE, она более удобочитаема для меня. 17.06.2014

  • 3

    Будет ли этого достаточно? (правда, я могу неправильно интерпретировать вопрос)

    SELECT
      F.ID AS ID,
      F.Color AS Color,
      B.Value AS Value
    FROM #Foo F
      LEFT OUTER JOIN #Bar B ON F.ID = FLOOR(B.Value)
    
    --this DOES seem to return the correct output, but I'm not sure that my logic
    --is what you are after
    SELECT
      F.ID AS ID,
      F.Color AS Color,
      B.Value AS Value
    FROM 
        (
          VALUES
            (1,'Red'),(2,'Green'),(3,'Blue'),(4, NULL)
        ) AS F(ID, Color)
      LEFT OUTER JOIN 
        (
          VALUES    
            (1), (2.5)
        ) AS B(Value) 
      ON F.ID = FLOOR(B.Value)
    

    Или вы хотите по существу:

    • Сортировать #Foo по идентификатору
    • Сортировать #Boo по значению
    • Match:
      • "First" row from #Foo with "First" row from #Bar
      • «Вторая» строка из #Foo со «Второй» строкой из #Bar
      • так далее...

    (Извините, но я не знаком с тем, что такое «ZIP JOIN». Однако я посмотрю ссылку, предоставленную @RszardDzegan.)

    23.01.2015
  • Мне нужно склеить две таблицы вместе независимо от их значений. Предположим, что у вас есть два набора результатов и вы хотите создать одну единую таблицу, собрав их вместе следующим образом: первая строка B рядом с первой строкой, вторая строка B рядом со второй строкой и т. д. Значения в таком сценарии не имеют значения. Просто ищу простое решение в SQL. 27.01.2015
  • В этом случае я считаю, что ваше решение с CTE, вероятно, будет лучшим выбором, просто обратите внимание на производительность. Я ОГРОМНЫЙ поклонник CTE и использую их везде, где могу найти причину, НО у меня были проблемы с производительностью, когда наборы результатов CTE возвращали большой объем данных. Большой обычно означает сто МБ или около того. Единственная другая проблема будет заключаться в том, что при работе с набором данных, что ТОЧНО означает first row и second row и т. д.? Предполагая, что существует НЕКОТОРЫЙ столбец, по которому строки могут логически сортироваться, дополнительным соображением будет то, что делать со связями. ФАНТАСТИЧЕСКИЙ ВОПРОС!! 29.01.2015

  • 4

    вы можете попробовать что-то вроде этого:

    DECLARE @Foo TABLE (Id INT, Color VARCHAR(10));
    DECLARE @Bar TABLE (Value DECIMAL(2, 1))
    
    INSERT INTO @Foo (Id, Color)
    VALUES (1, 'Red'), (2, 'Green'), (3, 'Blue'), (4, NULL)
    
    INSERT INTO @Bar (Value)
    VALUES (1), (2.5);
    
    WITH ECROSS
    AS (
        SELECT F.Id, F.Color, B.Value, DENSE_RANK() OVER (
                ORDER BY F.Id
                ) AS No1, DENSE_RANK() OVER (
                ORDER BY B.Value
                ) AS No2
        FROM @Foo F, @Bar B
        )
    SELECT A.id, A.Color, B.Value
    FROM ECROSS A
    LEFT JOIN ECROSS B ON A.No1 = B.No2
        AND A.No1 = B.No1
    GROUP BY A.id, A.Color, B.Value
    
    23.11.2015

    5

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

    WITH 
    CTE_FOO AS
    (
       SELECT
           [Group]
          ,[Spread]
          ,[Aggregate]
       FROM 
          (VALUES
              (1, 1, N'Red'  )
             ,(2, 1, N'Green')
             ,(3, 1, N'Blue' )
             ,(4, 1, NULL    )
          ) AS FOO([Group], [Spread], [Aggregate])
    ),
    CTE_BAR AS
    (
       SELECT
           [Group]
          ,[Spread]
          ,CAST([Aggregate] AS nvarchar(max)) AS [Aggregate]
       FROM 
          (VALUES
              (1, 2, 1   )
             ,(2, 2, 2.5 )
          ) AS BAR([Group], [Spread], [Aggregate])
    ),
    CTE_FOOBAR AS
    (
       SELECT [Group], [Spread], [Aggregate] FROM CTE_FOO
       UNION ALL
       SELECT [Group], [Spread], [Aggregate] FROM CTE_BAR   
    )
    SELECT 
        [Group] AS [ID]
       ,[1]     AS [Color]
       ,[2]     AS [Value]
    FROM
        CTE_FOOBAR
    PIVOT
        (
            MAX([Aggregate]) FOR [Spread] IN ([1], [2])
        ) AS PivotTable
    
    18.07.2016

    6

    Вы можете пропустить создание новых номеров строк для #Foo, так как его номера строк в этом случае заданы.

    Тогда решение станет

    SELECT F.Id,F.Color,newBar.Value from #Foo as F
    LEFT JOIN
    (
        SELECT [Value], ROW_NUMBER() OVER (ORDER BY [Value]) AS 'No'
        FROM #Bar
    ) newBar
    on F.Id=newBar.No
    

    Это решение проверено и проверено. Он дает вам все значения #Foo и для каждого отсортированное значение #Bar, если оно есть.

    05.02.2015
  • Я согласен, что в данном конкретном случае столбец [Id] действует как номер строки, но суть не в этом. Я ищу общее решение. 06.02.2015
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]