Как реализовать таблицу поиска для диапазона значений двух столбцов - PullRequest
4 голосов
/ 07 февраля 2012

Редактировать: обновлены две таблицы для синхронизации друг с другом. Это единственные задействованные таблицы. Проще говоря, мне нужно подсчитать все уникальные записи и отобразить их в 2d формате.

У меня есть таблица оптических линз, образец которой следует:

            Spherical|Cylindrical
            ---------------------
             0       |    0.5
             0.25    |    0.75
             0.25    |    0.5
             0       |    0
             0       |    0.25
             0       |    0.5
             0.25    |    0.75
             0.25    |    0.5
             0.5     |    0
             0.75    |    0
             0.75    |    0
             0.5     |    0.25
             0.5     |    0.75
             0.75    |    0.25
             0.5     |    0.75
             0.75    |    0.75
             0.75    |    0.5
             0.75    |    0.5

и так далее ...

Я хочу отобразить с высоты птичьего полета количество линз в каждой комбинации в формате 2d следующим образом:

Spherical/Cylindrical|0|0.25|0.5|0.75|... upto 8 in steps of 0.25
-----------------------------------------     
                 0   |1|  1 | 2 | 1  |
               0.25  |0|  0 | 2 | 2  |
               0.5   |1|  2 | 0 | 2  |
               0.75  |2|  1 | 2 | 1  |
                ...
               upto 30 in steps of 0.25

Как мне реализовать это в c # .net с sql server 2008? какой будет лучший подход?

У меня есть пара мыслей:

  1. Создайте представление во время выполнения, используя специальный запрос, и отформатируйте его в 2д
  2. Создайте 2d вид таблицы (в вышеуказанном формате) и обновите отсчитывать каждый раз при обновлении таблицы объективов.

Пожалуйста, дайте мне свои мысли и посоветуйте по этому поводу. Спасибо!

Ответы [ 2 ]

2 голосов
/ 09 февраля 2012

Заимствуя из табличной переменной KM, вот еще один способ сделать это, который использует PIVOT и избегает 33 SUM(CASE...) выражений.

DECLARE @Optical TABLE (Spherical DECIMAL(4,2), Cylindrical DECIMAL(4,2));

INSERT INTO @Optical VALUES (   0, 0.5);
INSERT INTO @Optical VALUES (0.25, 0.75);
INSERT INTO @Optical VALUES (1.25, 0.5);
INSERT INTO @Optical VALUES (1.25, 0.5);
INSERT INTO @Optical VALUES (   0, 0);

;WITH x AS 
(
    SELECT TOP (33) [row] = (ROW_NUMBER() 
        OVER (ORDER BY [object_id])-1)*0.25
        FROM sys.objects ORDER BY [row]
), y AS
(
    SELECT Spherical = x.[row], o.Cylindrical
        FROM x 
        LEFT OUTER JOIN @Optical AS o
        ON x.[row] = o.Spherical
)
SELECT pvt.* FROM y 
PIVOT (COUNT(y.Cylindrical) FOR y.Cylindrical IN 
(
  [0.00],[0.25],[0.50],[0.75],[1.00],[1.25],[1.50],[1.75],[2.00],[2.25],[2.50],[2.75],
  [3.00],[3.25],[3.50],[3.75],[4.00],[4.25],[4.50],[4.75],[5.00],[5.25],[5.50],[5.75],
  [6.00],[6.25],[6.50],[6.75],[7.00],[7.25],[7.50],[7.75],[8.00]
)) AS pvt
ORDER BY pvt.Spherical;

Теперь вы, вероятно, думаете, я неВы хотите ввести все эти значения в разделе PIVOT, но вы можете сгенерировать их довольно быстро:

DECLARE @sql NVARCHAR(MAX)= N'';

;WITH x AS 
(
    SELECT TOP (33) [row] = (ROW_NUMBER() 
        OVER (ORDER BY [object_id])-1)*0.25
        FROM sys.objects ORDER BY [row]
)
SELECT @sql = @sql + ',[' + RTRIM(CONVERT(DECIMAL(4,2), [row])) + ']' FROM x;

SET @sql = STUFF(@sql, 1, 1, '');

PRINT @sql;
2 голосов
/ 08 февраля 2012

Вот пример запроса о том, как сделать представление:

--build table variable and sample data
DECLARE @Optical table (Spherical numeric(4,2),Cylindrical numeric(4,2))
INSERT INTO @Optical VALUES (   0, 0.5)
INSERT INTO @Optical VALUES (0.25,0.75)
INSERT INTO @Optical VALUES (1.25, 0.5)
INSERT INTO @Optical VALUES (1.25, 0.5)
INSERT INTO @Optical VALUES (   0,  0)

--query to use as a basis for the view
;with AllSpherical AS --this recursive CTE builds the 121 rows for: 0.00 to 30.0
(
    SELECT convert(numeric(4,2),0.0) AS Spherical
    UNION ALL
    SELECT convert(numeric(4,2),Spherical+0.25)
        FROM AllSpherical
    WHERE Spherical<=29.75
)
SELECT 
    s.Spherical 
        ,SUM(CASE WHEN o.Cylindrical=0.00 THEN 1 ELSE 0 END) AS c_000
        ,SUM(CASE WHEN o.Cylindrical=0.25 THEN 1 ELSE 0 END) AS c_025
        ,SUM(CASE WHEN o.Cylindrical=0.50 THEN 1 ELSE 0 END) AS c_050
        ,SUM(CASE WHEN o.Cylindrical=0.75 THEN 1 ELSE 0 END) AS c_075
        ,SUM(CASE WHEN o.Cylindrical=1.00 THEN 1 ELSE 0 END) AS c_100
        ,SUM(CASE WHEN o.Cylindrical=1.25 THEN 1 ELSE 0 END) AS c_125
        ,SUM(CASE WHEN o.Cylindrical=1.50 THEN 1 ELSE 0 END) AS c_150
        ,SUM(CASE WHEN o.Cylindrical=1.75 THEN 1 ELSE 0 END) AS c_175
        --... add a case for all columns

    FROM AllSpherical              s
        LEFT OUTER JOIN @Optical   o ON s.Spherical=o.Spherical
    GROUP BY s.Spherical 
    OPTION (MAXRECURSION 120)

выход:

Spherical  c_000 c_025 c_050 c_075 c_100 c_125 c_150 c_175
---------- ----- ----- ----- ----- ----- ----- ----- -----
0.00       1     0     1     0     0     0     0     0
0.25       0     0     0     1     0     0     0     0
0.50       0     0     0     0     0     0     0     0
0.75       0     0     0     0     0     0     0     0
1.00       0     0     0     0     0     0     0     0
1.25       0     0     2     0     0     0     0     0
1.50       0     0     0     0     0     0     0     0
1.75       0     0     0     0     0     0     0     0
2.00       0     0     0     0     0     0     0     0
2.25       0     0     0     0     0     0     0     0
...

(121 row(s) affected)

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

если вы планируете читать это представление намного больше, чем обновлять необработанные данные, рассмотрите возможность сохранения представления: Повышение производительности с помощью индексированных представлений SQL Server 2005 и Создание индексированных представлений . Это в основном материализует представление, и когда вы вставляете / обновляете / удаляете базовую таблицу, сохраненные данные представления обновляются так же, как автоматический триггер системного уровня, чтобы поддерживать их синхронизацию. это будет ваш вариант 2, но система выполнит всю «тяжелую» работу по поддержанию синхронизации всего.

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