ЕСЛИ и ИНДЕКСИРОВАТЬ / СОПОСТАВЛЯТЬ АНАЛОГ EXCEL В SQL-ЗАПРОСЕ

#sql #sql-server #if-statement #case #where-clause

#sql #sql-сервер #if-оператор #случай #where-предложение

Вопрос:

Моя таблица выглядит следующим образом

 NAME        BRAND    REFERENCE       COMMENTS   <-Expected output
-------------------------------------------------
Gu          Skirt    101128           Pants
Cci         Pants    101127           Pants
Cha         Skirt    paired           paired
Gu          Pants    101128           Skirts
Nel         Skirt    nonpaired        UNIQUE
Gir         Pants    101188           Skirt
Baud        Skirt    dropped          DROPPED
Le          Pants    paired           PAIRED 
Gir         Skirt    101188           101178 
Vis         Socks                     blanks
Cci         Skirts   101127           Skirts
  

Интересно, какой код использовать для получения Comments результата.

Первая ссылка в NUMBERS должна быть сопряжена. Если номера ссылок совпадают, возвращаемое значение должно быть Brand аналогом.

Если ссылка Character включена, они должны подпадать под операторы if: ЕСЛИ символ непарный, возвращаемое значение должно быть уникальным, отбрасываться для отбрасывания и так далее. Если ссылка является пробелом, никаких изменений.

Возможно ли это?

Большое вам спасибо.

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

1. пожалуйста, опубликуйте пример вывода, моя дорогая

2. @Chels — Можете ли вы объяснить это на примере, первая ссылка в ЦИФРАХ должна быть сопряжена. Если ссылочные номера совпадают, возвращаемое значение должно быть аналогом бренда.

3. @Chels — Что делать, если совпадений более одного

4. @Chels Я добавил приведенный ниже ответ в соответствии с вашим запросом… Попробуйте запустить его и посмотреть, работает ли он…

5. Не порти свои сообщения.

Ответ №1:

Вы можете использовать общие табличные выражения для устранения проблемы, что может помочь в поддержании кода.

Я не использовал запаздывание / опережение, потому что у вас есть только две строки в паре, поэтому нумерация строк и объединение таблицы с самой собой ощущались быстрее и проще. следовать.

Вот код, который я использовал для ответа и проверки вашего вопроса;

 create table #source
(
    [NAME] varchar(200),
    [BRAND] varchar(200),
    [REFERENCE] varchar(200)
);

insert into #source values
    ('Gu','Skirt','101128'),
    ('Cci','Pants','101127'),
    ('Cha','Skirt','paired'),
    ('Gu','Pants','101128'),
    ('Nel','Skirt','nonpaired'),
    ('Gir','Pants','101188'),
    ('Baud','Skirt','dropped'),
    ('Le','Pants','paired'),
    ('Gir','Skirt','101188'),
    ('Vis','Socks',''),
    ('Cci','Skirts','101127'),
    ('Le','Socks','101188'),
    ('Uno','Socks','101101');

select * from #source;

with cteNumericRef as
(
    select [NAME],[BRAND],[REFERENCE]
    from #source
    where ISNUMERIC([REFERENCE]) = 1
)

, cteCheckRow as
(
    select [REFERENCE],
        'CHECK' as [COMMENT]
    from cteNumericRef
    group by [REFERENCE]
    having count(*) <> 2
)

, ctePairedRow as
(
    select
          num_ref.[NAME]
        , num_ref.[BRAND]
        , num_ref.[REFERENCE]
        , row_number() over (partition by num_ref.[REFERENCE] order by num_ref.[NAME]) as [Pair_Num]

    from cteNumericRef num_ref

    left join cteCheckRow check_row
        on check_row.[REFERENCE] = num_ref.[REFERENCE]

    where check_row.[REFERENCE] is null
)

, cteTextRow as
(
    select [NAME],[BRAND],[REFERENCE],
        case [REFERENCE]
            when 'paired' then 'PAIRED'
            when 'nonpaired' then 'UNIQUE'
            when 'dropped' then 'DROPPED'
            when '' then ''
        else 'CHECK' end as [COMMENT]
    from #source
    where ISNUMERIC([REFERENCE]) <> 1
)

select
    left_row.[NAME]
    , left_row.[BRAND]
    , left_row.[REFERENCE]
    , right_row.[BRAND] as [COMMENTS]
from ctePairedRow left_row
inner join ctePairedRow right_row
    on left_row.[REFERENCE] = right_row.[REFERENCE]
    and left_row.[Pair_Num] <> right_row.[Pair_Num]

union all

select
    num_ref.[NAME]
    , num_ref.[BRAND]
    , num_ref.[REFERENCE]
    , check_row.[COMMENT]
from cteNumericRef num_ref
inner join cteCheckRow check_row
    on check_row.[REFERENCE] = num_ref.[REFERENCE]

union all

select
      [NAME]
    , [BRAND]
    , [REFERENCE]
    , [COMMENT]
from cteTextRow;


drop table #source
  

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

1. Привет, я переделал некоторые из них. Потому что я нахожу ошибку именования. присвоение имен ссылкам

2. могу ли я запросить дополнительные изменения? ДЛЯ меня ЭТО СРАБОТАЛО отлично. При первом запуске у меня была опечатка. Однако мне нужно добавить значение частичного поиска для UID, УНИКАЛЬНОГО ИДЕНТИФИКАТОРА ЭЛЕМЕНТА. Не могли бы вы помочь?

3. Это дополнительная таблица, которую вы хотите присоединить ко всему результирующему набору? Если это так, вы можете обернуть конечный набор объединений как новый cte, затем присоедините результат этого cte один раз к вашей таблице поиска с помощью left join, если вы не ожидаете результатов для каждой строки. Можете ли вы расширить то, что вы спрашиваете?

4. @ edward, извините, вы можете меня направить? это похоже на мой первый раз в sql:((( не могли бы вы помочь в моем другом вопросе. Большое, большое спасибо

5. Привет, Эдвард. Я уже голосую. Но в нем говорится, что те, у кого репутация 15 ниже, подсчитываются, но не могут изменять публично отображаемые голоса.

Ответ №2:

 SELECT Name,
       Brand,
       Reference,
       CASE WHEN Reference = 'Paired' THEN 'Paired' 
            WHEN Reference = 'nonpaired' THEN 'Unique'
            WHEN Reference = 'dropped' THEN 'DROPPED'
            WHEN Reference = ' ' THEN 'blanks'
            WHEN Reference = Next_Ref AND rownum = 1 THEN next_brand
            WHEN Reference = Prev_Ref AND rownum = 2 THEN prev_brand
        END AS Comments
  FROM  
     (
       SELECT Name,
              Brand,
              Reference,
              LAG( Reference, 1 )OVER PARTITION BY ( Reference ORDER BY Brand ) AS Prev_Ref,
              LEAD( Reference, 1 )OVER PARTITION BY ( Reference ORDER BY Brand ) AS Next_Ref,
              LAG( Brand, 1 ) OVER PARTITION BY ( Reference ORDER BY Brand ) AS Prev_Brand,
              LEAD( Brand, 1 ) OVER PARTITION BY ( Reference ORDER BY Brand ) AS Next_Brand,
              ROW_NUMBER( ) OVER PARTITION BY ( Reference ORDER BY Brand ) AS rownum
         FROM Data
     ); 
  

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

1. спасибо @teja, я попробую это сейчас, если это сработает для меня! большое спасибо

2. не могли бы вы помочь, если есть ошибка в запаздывающей и ведущей части формулы

3. привет, первый случай, когда помогло.