Фильтрация оператора SELECT по строке с большинством заполненных столбцов - PullRequest
3 голосов
/ 14 июля 2009

У меня есть оператор, который ВЫБИРАЕТ отдельные строки из таблицы с индексом двух значений

SELECT distinct Reference, Value1, Value2, Value3, Value4 FROM [tblHistory]

Где Ссылка - это индекс с другим полем "Проект". Для конкретной системы эти данные вставляются в другую таблицу, используя в качестве индекса только ссылку, поскольку значения от 1 до 4 всегда должны быть одинаковыми для одной и той же ссылки, однако примерно в 1/500 это не так.

В случае, когда в одном или нескольких полях Value1-Value4 есть повторяющиеся ссылки и различия, мне нужно выбрать строку с наиболее заполненными полями Value1-Value4, поскольку они часто имеют значение NULL. Если все экземпляры имеют одинаковое количество заполненных столбцов, я могу вернуть первую найденную строку.

Кроме использования временных таблиц и кода типа

case when Value1 is null then 1 else 0 end 
+ case when Value2 is null then 1 else 0 end 
+ case when Value3 is null then 1 else 0 end
+ case when Value4 is null then 1 else 0 end
as CountOfNulls

Есть ли способ отфильтровать данные, чтобы я получил только наиболее заполненную строку?

Я использую MS SQL Server 2000.

Ответы [ 4 ]

1 голос
/ 14 июля 2009

-- count() will not include NULL, so we can avoid making complex conditions
;
with
sum_cnt
(
    Reference,
    cnt
)
as
(
    select 
        Reference, 
        count(Value1) + count(Value2) + count(Value3) + count(Value4) 
    from 
        tblHistory 
    group by 
        Reference
)
select top 1
    Reference
from
    sum_cnt 
order by
    cnt desc


1 голос
/ 14 июля 2009

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

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

1 голос
/ 14 июля 2009

Вы можете посмотреть на функцию Coalesce, но, честно говоря, я бы, наверное, сделал оператор Case, как вы сделали выше.

По какой причине вы не хотите его использовать?

Согласно комментариям, таблица - это не просто 4 поля значений. Но есть опасение, что потребуется временная таблица с наибольшим количеством нулей.

Мне кажется, что решение Case, потенциально реализованное в виде, все еще остается жизнеспособным и хорошим решением.

0 голосов
/ 14 июля 2009

Ну, это не очень хороший способ сделать это, но я собрал этот код, и он работает:

SELECT distinct Reference, Value1, Value2, Value3, Value4

FROM [tblHistory]
WHERE Reference+cast(4-(case when Value1 is null then 1 else 0 end 
+ case when Value2 is null then 1 else 0 end 
+ case when Value3 is null then 1 else 0 end
+ case when Value4 is null then 1 else 0 END) AS varchar) IN (

SELECT myref + CAST(MAX(CountOfNonNulls) AS VARCHAR) FROM
(

SELECT myref, 4-(case when Value1 is null then 1 else 0 end 
+ case when Value2 is null then 1 else 0 end 
+ case when Value3 is null then 1 else 0 end
+ case when Value4 is null then 1 else 0 end)
as CountOfNonNulls

FROM [tblHistory]
)l
GROUP BY Reference
)

У меня фактически нет этой структуры таблицы, поэтому я не проверял ее, но, похоже, она работает. Идея состоит в том, чтобы создать «новый» ключ, добавив наибольшее значение CountOfNonNulls в поле Reference и используя его для ограничения выбора - это означает, что неприятный код CASE запускается дважды, но другие фильтры, которые у меня есть (не показаны), ограничивают популяцию до примерно 80 строк в моей системе, поэтому я могу жить с этим.

Я еще не видел, что бы он сделал, если бы было две строки с одинаковым значением CountOfNonNulls, но с разными полями Value1-Value4 - думаю, он сломается. В этом случае я бы, вероятно, добавил бы поля Value1-Value4 к своему «новому» ключу, но это немного глупо.

Любые предложения по улучшению будет принята с благодарностью!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...