2013-05-27 3 views
1

У меня есть эта таблица BarCode, когда я делаю в запросе, как этотПочему оператор IN показывает неправильные результаты?

SELECT Barcode 
FROM BarcodeTable 
WHERE BarCode IN 
      (
       '53-3-1', 
       '51-1-1', 
       '51-2-1', 
       '50-10-1', 
       '50-8-1', 
       '51-4-1', 
       '50-1-1' 
      ) 

почему я получаю

53-3-1 
50-1-1 
50-8-1 
50-10-1 
51-1-1 
51-2-1 
51-4-1 

Вместо ????

53-3-1 
51-1-1 
51-2-1 
50-10-1 
50-8-1 
51-4-1 
50-1-1 

Почему SQL изменяет порядок штрих-кодов? Из-за того, как SQL упорядочивает их (сам по себе), возникает ошибка в динамическом запросе, который выполняется sp_executesql, который зависит от заказа, который я отправляю. Почему SQL меняет порядок ввода?

51-4-1

ответ

3

IN не подразумевает упорядочение конечного результата:

Это SQL:

... WHERE x IN (1, 2, 3) 

должны производить те же результаты, как это:

... WHERE x IN (3, 2, 1) 

Предложение IN только фильтрует строки, в основном, для каждой строки, которую вы можете думать об этом, просто спрашивая «должна ли эта строка быть частью набора результатов?».

Чтобы получить конкретный заказ, вам нужно добавить в ваше заявление предложение ORDER BY.

Чтобы получить конкретный заказ, вы можете использовать встроенную таблицу:

SELECT Barcode 
FROM BarcodeTable 
    inner join (values 
     ('*53-3-1*', 1), 
     ('*51-1-1*', 2), 
     ('*51-2-1*', 3), 
     ('*50-10-1*', 4), 
     ('*50-8-1*', 5), 
     ('*51-4-1*', 6), 
     ('*50-1-1*', 7)) as DummyTable (value, sortorder) 
    on BarCode = value 
order by 
    sortorder 

Это заказ на SortOrder поля DummyTable.

Вы не можете обмануть SQL Server в использовании пункта самого IN для заказа, вы имеете добавить ORDER BY в той или иной форме.

Вы также можете использовать выражение CASE WHEN ... для получения значения порядка сортировки в зависимости от штрих-кода:

SELECT Barcode 
FROM BarcodeTable 
WHERE BarCode IN ('*53-3-1*', '*51-1-1*', '*51-2-1*', '*50-10-1*', '*50-8-1*', '*51-4-1*', '*50-1-1*') 
ORDER BY 
    CASE BarCode 
     WHEN '*53-3-1*' THEN 1 
     WHEN '*51-1-1*' THEN 2 
     WHEN '*51-2-1*' THEN 3 
     WHEN '*50-10-1*' THEN 4 
     WHEN '*50-8-1*' THEN 5 
     WHEN '*51-4-1*' THEN 6 
     WHEN '*50-1-1*' THEN 7 
    END 

Как замечанием Ливен предполагает, что есть альтернатива на SQL Server 2005, используя предложение WITH:

WITH DummyTable (value, sortorder) AS (
    SELECT '*53-3-1*' AS value, 1 AS sortorder 
    UNION ALL 
    SELECT '*51-1-1*', 2 
    UNION ALL 
    SELECT '*51-2-1*', 3 
    UNION ALL 
    SELECT '*50-10-1*', 4 
    UNION ALL 
    SELECT '*50-8-1*', 5 
    UNION ALL 
    SELECT '*51-4-1*', 6 
    UNION ALL 
    SELECT '*50-1-1*', 7 
) 
SELECT Barcode 
FROM BarcodeTable 
    inner join DummyTable 
    on BarCode = value 
order by 
    sortorder 

(обратите внимание, что я не эксперт в использовании WITH, выше было только то, что я взломал вместе, но, кажется, работает)

+0

Есть ли способ, я могу выводить данные в порядке, я указал вход для 'в'? Поскольку выполняемый запрос является динамическим sql, и он зависит от порядка, в котором он был указан. Я знаю, что могу использовать курсор, но я не хочу этого делать. – Razort4x

+0

Примечание. Я не уверен, что синтаксис «VALUES» работает в SQL Server 2005. Я тестировал это только в 2008 году. –

+0

+1. 2005 не имеет конструктора значений, но вы можете получить тот же эффект, используя оператор 'with'. –

3

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

1

Чтобы сделать заказ, как вы ожидаете, вам нужно добавить ORDER BY, или заказ будет ненадежным.Что-то вроде этого должно работать, но в зависимости от вашего объема штрих-кодов, в конце концов, может быть проще заказать его правильно в коде после возвращения результата;

SELECT Barcode 
FROM BarcodeTable 
WHERE BarCode IN ('*53-3-1*','*51-1-1*','*51-2-1*','*50-10-1*', 
        '*50-8-1*','*51-4-1*','*50-1-1*') 
ORDER BY CASE BarCode WHEN '*53-3-1*' THEN 1 
         WHEN '*51-1-1*' THEN 2 
         WHEN '*51-2-1*' THEN 3 
         WHEN '*50-10-1*' THEN 4 
         WHEN '*50-8-1*' THEN 5 
         WHEN '*51-4-1*' THEN 6 
         WHEN '*50-1-1*' THEN 7 
         END 
0

Try Ниже кодекса

SELECT Barcode ,CASE Col_Order WHEN '53-3-1' THEN 1 
         WHEN '51-1-1' THEN 2 
         WHEN '51-2-1' THEN 3 
         WHEN '50-10-1' THEN 4 
         WHEN '50-8-1' THEN 5 
         WHEN '51-4-1' THEN 6 
         WHEN '50-1-1' THEN 7 
         END  
FROM BarcodeTable 
WHERE BarCode IN 
      (
       '53-3-1', 
       '51-1-1', 
       '51-2-1', 
       '50-10-1', 
       '50-8-1', 
       '51-4-1', 
       '50-1-1' 
      )  
ORDER BY Col_Order