SQL-CE возможная ошибка? - PullRequest
       6

SQL-CE возможная ошибка?

4 голосов
/ 12 августа 2011

Если я выполню этот запрос, все значения [data]. * Получат значение NULL. игнорировать *, это просто тест

SELECT
  [map].*,
  [data].*
FROM
  f_normalised_report_hierarchy     AS [map]
LEFT JOIN
  f_normalised_report_data          AS [data]
    ON  (([data].level1_id = [map].level1_id) OR ([data].level1_id = 0))
    AND (([data].level2_id = [map].level2_id) OR ([data].level2_id = 0))
    AND (([data].level3_id = [map].level3_id) OR ([data].level3_id = 0))
    AND (([data].level4_id = [map].level4_id) OR ([data].level4_id = 0))
    AND (([data].level5_id = [map].level5_id) OR ([data].level5_id = 0))
    AND (([data].level6_id = [map].level6_id) OR ([data].level6_id = 0))
    AND ([data].metric_id = 22)
WHERE
  [map].level1_id = 22


Тем не менее, это работает нормально, если я добавлю 1=1 AND перед каждым [data].levelX_id = 0!?!?

SELECT
  [map].*,
  [data].*
FROM
  f_normalised_report_hierarchy     AS [map]
LEFT JOIN
  f_normalised_report_data          AS [data]
    ON  (([data].level1_id = [map].level1_id) OR (1=1 AND [data].level1_id = 0))
    AND (([data].level2_id = [map].level2_id) OR (1=1 AND [data].level2_id = 0))
    AND (([data].level3_id = [map].level3_id) OR (1=1 AND [data].level3_id = 0))
    AND (([data].level4_id = [map].level4_id) OR (1=1 AND [data].level4_id = 0))
    AND (([data].level5_id = [map].level5_id) OR (1=1 AND [data].level5_id = 0))
    AND (([data].level6_id = [map].level6_id) OR (1=1 AND [data].level6_id = 0))
    AND ([data].metric_id = 22)
WHERE
  [map].level1_id = 22


Я мог бы почти с этим жить, как выдумка, чтобы заставить это работать, но теперь это требует вечности, чтобы бежать. (Увеличено с менее чем за секунду до «все еще работает» через 6 минут.)

Меня связывают? Или SQL CE выключен?

EDIT

Если я отменю условия:

    AND (([data].level6_id = [map].level6_id) OR ([data].level6_id = 0))

до

    AND (([data].level6_id = 0) OR ([data].level6_id = [map].level6_id))

тогда у меня другое поведение.


И если я вместо этого использую IN:

    AND ([data].level6_id IN ([map].level6_id,0))

Я по-прежнему веду себя по-другому.


Ни одно из поведений, которые не чувствуют, и, конечно, не то, что я кодировал.

Ответы [ 2 ]

3 голосов
/ 13 августа 2011

Я предполагаю, что они, вероятно, медленнее, но я получил оба этих запроса для работы:

SELECT
    *
FROM
  f_normalised_report_hierarchy     AS [map]
LEFT JOIN
  f_normalised_report_data          AS [data]
      ON  ([data].level1_id = [map].level1_id OR [data].level1_id*1 = 0)
      AND ([data].level2_id = [map].level2_id OR [data].level2_id*1 = 0)
      AND ([data].level3_id = [map].level3_id OR [data].level3_id*1 = 0)
      AND ([data].level4_id = [map].level4_id OR [data].level4_id*1 = 0)
      AND ([data].level5_id = [map].level5_id OR [data].level5_id*1 = 0)
      AND ([data].level6_id = [map].level6_id OR [data].level6_id*1 = 0)
;

И

SELECT
    *
FROM
  f_normalised_report_hierarchy     AS [map]
LEFT JOIN
  f_normalised_report_data          AS [data]
      ON  ([data].level1_id = [map].level1_id OR cast([data].level1_id as int) = 0)
      AND ([data].level2_id = [map].level2_id OR cast([data].level2_id as int) = 0)
      AND ([data].level3_id = [map].level3_id OR cast([data].level3_id as int) = 0)
      AND ([data].level4_id = [map].level4_id OR cast([data].level4_id as int) = 0)
      AND ([data].level5_id = [map].level5_id OR cast([data].level5_id as int) = 0)
      AND ([data].level6_id = [map].level6_id OR cast([data].level6_id as int) = 0)
;

РЕДАКТИРОВАТЬ С Compact 4, если это имеет значение.

1 голос
/ 12 августа 2011

Мое решение состоит в том, чтобы отказаться от SQL-CE и выполнить объединение памяти в клиенте.

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

CREATE TABLE f_normalised_report_data (
    level1_id       INT,
    level2_id       INT,
    level3_id       INT,
    level4_id       INT,
    level5_id       INT,
    level6_id       INT,
    metric_id       INT,
    value           MONEY,
    PRIMARY KEY (
        level1_id,
        level2_id,
        level3_id,
        level4_id,
        level5_id,
        level6_id,
        metric_id
    )
)
;

CREATE TABLE f_normalised_report_hierarchy (
    level1_id       INT,
    level2_id       INT,
    level3_id       INT,
    level4_id       INT,
    level5_id       INT,
    level6_id       INT,
    PRIMARY KEY (
        level1_id,
        level2_id,
        level3_id,
        level4_id,
        level5_id,
        level6_id
    )
)
;

INSERT INTO f_normalised_report_hierarchy SELECT 1, 2, 3, 4, 5, 6;
INSERT INTO f_normalised_report_hierarchy SELECT 1, 2, 3, 4, 5, 7;

INSERT INTO f_normalised_report_data      SELECT 1, 2, 3, 0, 5, 6, 22, 999;
INSERT INTO f_normalised_report_data      SELECT 1, 2, 3, 0, 5, 7, 22, 911;

SELECT
    *
FROM
  f_normalised_report_hierarchy     AS [map]
LEFT JOIN
  f_normalised_report_data          AS [data]
      ON  ([data].level1_id = [map].level1_id OR [data].level1_id = 0)
      AND ([data].level2_id = [map].level2_id OR [data].level2_id = 0)
      AND ([data].level3_id = [map].level3_id OR [data].level3_id = 0)
      AND ([data].level4_id = [map].level4_id OR [data].level4_id = 0)
      AND ([data].level5_id = [map].level5_id OR [data].level5_id = 0)
      AND ([data].level6_id = [map].level6_id OR [data].level6_id = 0)
;
-- The above query gives me this...
-- 1, 2, 3, 4, 5, 6, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-- 1, 2, 3, 4, 5, 7, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL

SELECT
    *
FROM
  f_normalised_report_hierarchy     AS [map]
LEFT JOIN
  f_normalised_report_data          AS [data]
      ON  ([data].level1_id = 0 OR [data].level1_id = [map].level1_id)
      AND ([data].level2_id = 0 OR [data].level2_id = [map].level2_id)
      AND ([data].level3_id = 0 OR [data].level3_id = [map].level3_id)
      AND ([data].level4_id = 0 OR [data].level4_id = [map].level4_id)
      AND ([data].level5_id = 0 OR [data].level5_id = [map].level5_id)
      AND ([data].level6_id = 0 OR [data].level6_id = [map].level6_id)
;
-- The above query gives me this...
-- 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 0, 6, 22, 999
-- 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 0, 7, 22, 911
-- 1, 2, 3, 4, 5, 7, 1, 2, 3, 4, 0, 6, 22, 999
-- 1, 2, 3, 4, 5, 7, 1, 2, 3, 4, 0, 7, 22, 911


SELECT
    *
FROM
  f_normalised_report_hierarchy     AS [map]
LEFT JOIN
  f_normalised_report_data          AS [data]
      ON  ([data].level1_id IN ([map].level1_id, 0))
      AND ([data].level2_id IN ([map].level2_id, 0))
      AND ([data].level3_id IN ([map].level3_id, 0))
      AND ([data].level4_id IN ([map].level4_id, 0))
      AND ([data].level5_id IN ([map].level5_id, 0))
      AND ([data].level6_id IN ([map].level6_id, 0))
;
-- The above query gives me this...
-- 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 0, 6, 22, 999
-- 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 0, 7, 22, 911
-- 1, 2, 3, 4, 5, 7, 1, 2, 3, 4, 0, 6, 22, 999
-- 1, 2, 3, 4, 5, 7, 1, 2, 3, 4, 0, 7, 22, 911


SELECT
    *
FROM
  f_normalised_report_hierarchy     AS [map]
LEFT JOIN
  f_normalised_report_data          AS [data]
      ON  ([data].level1_id = [map].level1_id OR (1=1 AND [data].level1_id = 0))
      AND ([data].level2_id = [map].level2_id OR (1=1 AND [data].level2_id = 0))
      AND ([data].level3_id = [map].level3_id OR (1=1 AND [data].level3_id = 0))
      AND ([data].level4_id = [map].level4_id OR (1=1 AND [data].level4_id = 0))
      AND ([data].level5_id = [map].level5_id OR (1=1 AND [data].level5_id = 0))
      AND ([data].level6_id = [map].level6_id OR (1=1 AND [data].level6_id = 0))
;
-- The above query gives me this...
-- 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 0, 6, 22, 999
-- 1, 2, 3, 4, 5, 7, 1, 2, 3, 4, 0, 7, 22, 911
--
-- Which is correct, but performance was blown to smitherines.
...