В HTML (включая XHTML), который используется на веб-страницах, DOCTYPE - это строка, которая запускает один из нескольких режимов браузера (режим quirks, режим стандартов, почти стандартный режим), в зависимости от точного написания DOCTYPE. Вы хотите использовать его для выбора режима браузера, который наилучшим образом соответствует вашей странице.
Формально, в SGML и XML объявление DOCTYPE является ссылкой на определение типа документа (DTD), которое определяет формальный синтаксис правила языка разметки. Ни один браузер никогда не использовал DTD для чего-либо или даже не обращался к ним. Тем не менее, они используются валидаторами разметки SGML и XML, такими как W3C Markup Validator , за исключением режима HTML5. Поэтому выбор DOCTYPE определяет, как работает валидатор, если документ будет отправлен на него. Однако режим работы валидатора также может быть выбран в его пользовательском интерфейсе. (SGML и XML-процессоры могут использовать DOCTYPE и другими способами, но вопрос, по-видимому, должен ограничиваться контекстом HTML и веб-браузерами и тесно связанными с ним программными средствами.)
Нет авторитетного списка DOCTYPE. Каждая спецификация или проект HTML определяет собственный DOCTYPE или DOCTYPE. Набор DOCTYPE, распознаваемый браузерами при выборе режима, зависит от браузера. На практике нет причин использовать DOCTYPE, кроме
, как определено в HTML5 , хотя HTML5 также содержит несколько «устаревших DOCTYPE». Вы можете использовать этот DOCTYPE, если вы хотите режим стандартов (рекомендуется для новых страниц), и не используйте DOCTYPE, если вы хотите режим quirks (который может понадобиться для устаревших страниц).
«Режим стандартов» обычно означает режим где браузер следует за HTML, CSS, DOM и другими спецификациями, насколько это возможно. Обычно это не означает полное соответствие. «Режим Quirks» отличается в разных браузерах, но в целом это означает попытку имитировать поведение очень старых браузеров, таких как IE 5. Целью является сохранение старых страниц в предположении, что они могут полагаться на функции и ошибки в старых браузеров. См. Описание Что происходит в режиме Quirks? Обратите внимание, что в HTML5 существует довольно разная, более ограниченная концепция режима «quirks», которая очень напоминает документ под названием Quirks Mode Living Standard .
Типичная проблема заключается в том, что ширина элементов вычисляется по-разному в режиме quirks и в стандартном режиме. Это означает, что макет страницы может быть более или менее изменен или даже полностью испорчен, если страница, предназначенная для работы в режиме quirks, просматривается в режиме стандартов (или наоборот).
Итак, вы должны используйте для новых страниц и сохраните любой DOCTYPE (если есть), который вы использовали для старых страниц.
Однако режим quirks означает, что в некоторых браузерах многие новые функции CSS не поддерживаются. Это означает, что если вы хотите улучшить старую страницу с помощью некоторой функции CSS3, вполне возможно, что вам необходимо переключиться на DOCTYPE, который запускает режим стандартов. В таком случае вам нужно просмотреть и проверить страницу, чтобы увидеть, будет ли она работать в стандартном режиме.
Это слишком долго для комментариев, поэтому я публикую это как ответ. Я хочу отметить, что это статический пример, но я надеюсь, что его можно легко перевести как динамическое утверждение.
Шаги записываются как комментарии в утверждении:
WITH rcte AS
(
-- Recursive query to generate all numbers from 1 to 4
SELECT 0 AS Number
UNION ALL
SELECT Number + 1
FROM rcte
WHERE Number < 4
), permutations AS (
-- All possible permutations with sum equal to 4
-- There is additional column DuplicateMarker.
-- It will be used later, because 0,0,0,4 and 0,4,0,0 are the same
SELECT
t1.Number AS Number1,
t2.Number AS Number2,
t3.Number AS Number3,
t4.Number AS Number4,
CONCAT(LTRIM(STR(t1.Number)), '.', LTRIM(STR(t2.Number)), '.', LTRIM(STR(t3.Number)), '.', LTRIM(STR(t4.Number))) AS DuplicateMarker
FROM rcte t1, rcte t2, rcte t3, rcte t4
WHERE (t1.Number + t2.Number + t3.Number + t4.Number) = 4
), duplicates AS (
-- Get data with splitted DuplicateMarker column
SELECT *
FROM permutations
CROSS APPLY (SELECT [value] FROM STRING_SPLIT(DuplicateMarker, '.')) t
), results AS (
-- Get unique combinations
-- WITHIN GROUP (ORDER BY) will order strings and 0.0.0.4 and 0.4.0.0 will be the same
SELECT DISTINCT STRING_AGG([value], '.') WITHIN GROUP (ORDER BY [value]) AS ScenarioValue
FROM duplicates
GROUP BY Number1, Number2, Number3, Number4
)
SELECT
DENSE_RANK() OVER (ORDER BY r.ScenarioValue) AS ScenarioID,
s.[value]
FROM results r
CROSS APPLY (SELECT [value] FROM STRING_SPLIT(r.ScenarioValue, '.')) s
WHERE [value] <> '0'
Вывод:
ScenarioID value
1 4
2 1
2 3
3 2
3 2
4 1
4 1
4 2
5 1
5 1
5 1
5 1
Обновление:
Благодаря комментарию @ AndriyM я сделал некоторые изменения и теперь вы можете исключить манипуляции со строками:
WITH rcte AS
(
-- Recursive query to generate all numbers from 0 to 4
SELECT 0 AS Number
UNION ALL
SELECT Number + 1
FROM rcte
WHERE Number < 4
), combinations AS (
-- All different combinations with sum equal to 4
SELECT
t1.Number AS Number1,
t2.Number AS Number2,
t3.Number AS Number3,
t4.Number AS Number4,
ROW_NUMBER() OVER (ORDER BY t1.Number, t2.Number, t3.Number, t4.NUmber) AS ScenarioID
FROM rcte t1, rcte t2, rcte t3, rcte t4
WHERE
((t1.Number + t2.Number + t3.Number + t4.Number) = 4) AND
(t1.Number <= t2.Number) AND
(t2.Number <= t3.Number) AND
(t3.Number <= t4.Number)
)
SELECT c.ScenarioID, v.[value]
FROM combinations c
CROSS APPLY (VALUES (c.NUmber1), (c.Number2), (c.Number3), (c.Number4)) AS v ([value])
WHERE v.[value] > 0
Обновление 2:
Подход с использованием динамического оператора - возможно, не лучший подход, но основан на утверждении из первого обновления: [1110 ]
-- Set your @n value
DECLARE @n int
SET @n = 4
-- Declarations
DECLARE @combinationsSelect nvarchar(max)
DECLARE @combinationsRowNumber nvarchar(max)
DECLARE @combinationsFrom nvarchar(max)
DECLARE @combinationsWhere1 nvarchar(max)
DECLARE @combinationsWhere2 nvarchar(max)
DECLARE @combinationsValues nvarchar(max)
SET @combinationsSelect = N''
SET @combinationsRowNumber = N''
SET @combinationsFrom = N''
SET @combinationsValues = N''
SET @combinationsWhere1 = N''
SET @combinationsWhere2 = N''
-- Generate dynamic parts of the statement
;WITH numbers AS
(
SELECT 1 AS Number
UNION ALL
SELECT Number + 1
FROM Numbers
WHERE Number < @n
)
SELECT
@combinationsSelect = @combinationsSelect + N', t' + LTRIM(STR(Number)) + N'.Number AS Number' + LTRIM(STR(Number)),
@combinationsRowNumber = @combinationsRowNumber + N', t' + LTRIM(STR(Number)) + N'.Number',
@combinationsValues = @combinationsValues + N', (c.Number' + LTRIM(STR(Number)) + N')',
@combinationsFrom = @combinationsFrom + N', rcte t' + LTRIM(STR(Number)),
@combinationsWhere1 = @combinationsWhere1 + N'+ t' + LTRIM(STR(Number)) + N'.Number ',
@combinationsWhere2 = @combinationsWhere2 +
CASE
WHEN Number = 1 THEN N''
ELSE N'AND (t' + LTRIM(STR(Number-1)) + N'.Number <= t' + + LTRIM(STR(Number)) + N'.Number) '
END
FROM
numbers
SET @combinationsSelect = STUFF(@combinationsSelect, 1, 2, N'')
SET @combinationsRowNumber = STUFF(@combinationsRowNumber, 1, 2, N'')
SET @combinationsValues = STUFF(@combinationsValues, 1, 2, N'')
SET @combinationsFrom = STUFF(@combinationsFrom, 1, 2, N'')
SET @combinationsWhere1 = STUFF(@combinationsWhere1, 1, 2, N'')
SET @combinationsWhere2 = STUFF(@combinationsWhere2, 1, 4, N'')
-- Dynamic statement
DECLARE @stm nvarchar(max)
SET @stm =
N'WITH rcte AS (
SELECT 0 AS Number
UNION ALL
SELECT Number + 1
FROM rcte
WHERE Number < ' + LTRIM(STR(@n)) +
N'), combinations AS (
SELECT ' +
@combinationsSelect +
N', ROW_NUMBER() OVER (ORDER BY ' + @combinationsRowNumber + N') AS ScenarioID
FROM ' + @combinationsFrom +
N' WHERE ((' + @combinationsWhere1 + N') = ' + LTRIM(STR(@n)) + ') AND ' + @combinationsWhere2 +
N')
SELECT c.ScenarioID, v.[value]
FROM combinations c
CROSS APPLY (VALUES ' + @combinationsValues + N') AS v ([value])
WHERE v.[value] > 0'
-- Execute dynamic statement
EXEC (@stm)