Проблема SQL-запроса

Для IE http://support.microsoft.com/kb/980077

должно быть что-то подобное для И следующие

p.s., Вы не можете установить это для клиентов!

p.s.2. можно заменить это звезды передними изображениями (абсолютный в случае необходимости) в css (медиа = "печать").

9
задан Res Cogitans 6 October 2009 в 07:47
поделиться

8 ответов

с помощью аналитики вы можете создать запрос, который будет выполнять один проход данных (с большим набором данных это будет наиболее эффективным):

SELECT machineid, MIN(start_time), MAX(end_time)
  FROM (SELECT machineid, start_time, end_time, 
               SUM(gap) over(PARTITION BY machineid 
                             ORDER BY start_time) contiguous_faults
           FROM (SELECT machineid, start_time, 
                        coalesce(end_time, DATE '9999-12-31') end_time,
                         CASE
                            WHEN start_time > MAX(coalesce(end_time, 
                                                           DATE '9999-12-31'))
                                              over(PARTITION BY machineid 
                                                   ORDER BY start_time 
                                                   ROWS BETWEEN UNBOUNDED PRECEDING
                                                            AND 1 preceding)
                            THEN 1
                         END gap
                    FROM faults))
 GROUP BY machineid, contiguous_faults
 ORDER BY 1, 2

Этот запрос начинается с определения, строка смежна с любой строкой, которая началась раньше. Затем мы группируем смежные строки.

7
ответ дан 3 November 2019 в 01:02
поделиться

По сути, вы не можете сделать это (найти покрывающее множество разбиений леса) в чистой теории множеств (например, как ограниченное количество запросов без цикла).

Чтобы сделать это наиболее похожим на набор способом,

  1. Создайте временную таблицу для разделения леса (10 или 11 столбцов, 4 из ошибки №1, 4 из ошибки №2, 1 для идентификатора раздела, 1 для раунда, в который был вставлен узел, и 1 для различных оптимизаций, о которых я не могу вспомнить с температурой 38C.

  2. Запустите цикл (BFS или DFS, что бы вы ни нашли, чтобы упростить реализацию алгоритма разделения леса). Сложная часть, по сравнению с графиками, заключается в что у вас может быть много поддеревьев, соединенных сверху с текущим поддеревом

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

  3. Когда цикл разбиения завершен,просто сделайте

   select min(p1.start_time), max(p2.end_time), p1.partition,p2.partition
   from partitions p1, partitions p2
   where p1.partition = p2.partition
   group by p1.partition,p2.partition


    /* This will need to be tweaked using COALESCE 
       to deal with NULL end times in obvious way) */

Прошу прощения за то, что не написали точный код для разбиения леса (он может быть записан в разделе разбиения на дерево) - я очень устал и уверен, что поиск в Google даст код, теперь, когда вы знаете структуру tdata и проблему имя (или вы можете опубликовать это как более точно сформулированный вопрос в StackOverflow - например, «Как реализовать алгоритм для полного разбиения леса деревьев в виде цикла в SQL».

2
ответ дан 3 November 2019 в 01:02
поделиться
SELECT machineid, min(start_time), max(ifnull(end_time, '3000-01-01 00:00'))
FROM faults
GROUP BY machineid

должен выполнить эту работу (при необходимости заменив ifnull эквивалентной функцией Oracle).

0
ответ дан 3 November 2019 в 01:02
поделиться
SELECT  DISTINCT 
        t1.machineId, 
        MIN(t2.start_time) start_time, 
        MAX(COALESCE(t2.end_time, '3210/01/01')) end_time
FROM FAULTS t1
JOIN FAULTS t2 ON t1.machineId = t2.machineId
                  AND ((t2.start_time >= t1.start_time
                       AND (t1.end_time IS NULL OR t2.start_time <= t1.end_time)
                  )
                  OR
                  (t1.start_time >= t2.start_time 
                       AND (t2.end_time IS NULL OR t1.start_time <= t2.end_time) 
                  ))
GROUP BY t1.machineId, t1.part_id

Я проверил этот запрос на следующих данных:

machine_id   |part_id |start_time           |end_time
-------------------------------------------------------------------------
1           |2       |05 Oct 2009 09:00:00  |NULL
1           |3       |05 Oct 2009 08:00:00  |05 Oct 2009 10:00:00
2           |2       |30 Sep 2009 12:00:00  |30 Sep 2009 14:00:00
2           |3       |30 Sep 2009 15:00:00  |30 Sep 2009 16:00:00
2           |4       |30 Sep 2009 16:00:00  |30 Sep 2009 17:00:00
3           |2       |28 Sep 2009 12:00:00  |28 Sep 2009 14:00:00
3           |4       |28 Sep 2009 13:00:00  |28 Sep 2009 15:00:00

Я получил это:

machine_id   |start_time             |end_time
-----------------------------------------------------------------
1           |05 Oct 2009 08:00:00   |01 Jan 3210 00:00:00
2           |30 Sep 2009 12:00:00   |30 Sep 2009 14:00:00
2           |30 Sep 2009 15:00:00   |30 Sep 2009 17:00:00
3           |28 Sep 2009 12:00:00   |28 Sep 2009 15:00:00
2
ответ дан 3 November 2019 в 01:02
поделиться

Хотел бы я дать полный ответ, но вот подсказка, чтобы найти перекрывающиеся простои:

select a.machineid, a.start_time, a.end_time, b.start_time, b.end_time
from faults a,
     faults b,
where a.machineid = b.machineid
  and b.start_time >= a.start_time
  and b.start_time <= a.end_time;
0
ответ дан 3 November 2019 в 01:02
поделиться

Я считаю, что для этого вам понадобится хранимая процедура или что-то вроде рекурсивных общих табличных выражений (CTE) (как существует в SQL srever) или иначе (в одном операторе SQL) вы не сможете получить правильный ответ, если 3 или более строк вместе образуют непрерывный диапазон охватываемых дат.

например:

 |----------|
           |---------------|
                        |----------------|

Фактически не выполняя упражнение, я мог бы предложить, чтобы в сохраненной процедуре построить таблицу всех «кандидатных дат», а затем построить таблицу, содержащую все даты, которые НЕ охвачены диапазоном дат в существующей строке, а затем создайте выходной набор результатов, "отрицая" этот набор.

0
ответ дан 3 November 2019 в 01:02
поделиться

Хе-хе.

В SIRA_PRISE, который поддерживает интервальные типы, решить эту проблему так же просто, как

SELECT machineID, period FROM Faults.

IN где 'period' - атрибут типа временного интервала, начальная и конечная точки которого - start_time и end_time вашей таблицы SQL.

Но поскольку вы, вероятно, вынуждены решать эту проблему в SQL, и с системой, которая не поддерживает типы интервалов, я могу только желаю вам много храбрости.

Два совета:

Объединение двух интервалов может быть обработано в SQL с использованием сложных конструкций CASE (если interval_values_overlap, то low_start_time, high_end_time, и все такое).

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

0
ответ дан 3 November 2019 в 01:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: