Я создал сводный запрос, в котором я хочу, чтобы динамические «столбцы» перекрестных применений сортировались особым образом, а они не будут.
Вот как возвращаются динамические «столбцы»:
[Cd - Conc] [Cd - RL] [Cd - Q] [Cd - MDL]
Вот как я хочу, чтобы они вернулись:
[Cd - Conc] [Cd - Q] [Cd - MDL] [Cd - RL]
Я ограничил свой запрос одним аналитом "Cd", в то время как я пытаюсь получить порядок сортировки, как описано выше, но общее количество аналитов не обязательно известно. Я хочу, чтобы они упорядочивали по аналиту по conc, q, mdl, rl, чтобы это выглядело как [Cd - Conc] [Cd - Q] [Cd - MDL] [Cd - RL] [Se - Conc] [Se - Q] [Se - MDL] [Se - RL] [Zr - Conc] [Zr - Q] [Zr - MDL] [Zr - RL] и т. Д.
Это мой код:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--
-- This variable holds the field values that will pivot to become column headers.
--
DECLARE @cols nvarchar(max);
--
-- This variable holds the dynamic pivot query.
--
DECLARE @query nvarchar(max);
--
-- First, we need to get the dynamic 'columns'. We do this by replicating
-- the FROM and WHERE clause that will show up in the pivot query. In the
-- SELECT, we only need to create the dynamic 'columns'. We must replicate
-- the FROM and WHERE clause or we'll end up with all rows from AN.[abbreviation].
--
-- This query is inside the STUFF function, which can build a string without
-- resorting to looping constructs.
--
-- The QUOTENAME function wraps a string in brackets, e.g. my_col becomes [my_col].
--
-- The end result of this is we get a comma-separated string of the form:
-- [Ag],[As], ...
--
SELECT @cols = STUFF
(
(
SELECT DISTINCT
',' + QUOTENAME(AN.[abbreviation] + col)
FROM
[project] P
INNER JOIN [monitoring_event_type] MET ON P.[id] = MET.[project_id]
INNER JOIN [monitoring_event] ME ON MET.[id] = ME.[event_type_id]
INNER JOIN [sample] S ON ME.[id] = S.[event_id]
INNER JOIN [location] L ON L.[id] = S.[location_id]
INNER JOIN [analysis] A ON A.[sample_id] = S.[id]
INNER JOIN [result] R ON R.[analysis_id] = A.[id]
INNER JOIN [result_qualifier] RQ ON RQ.[id] = R.[id]
LEFT JOIN [result_validation] RV ON RV.[id] = R.[id]
LEFT JOIN [sample_type] ST ON ST.[id] = R.[sample_type_id]
INNER JOIN [analyte] AN ON AN.[id] = R.[analyte_id]
LEFT JOIN [parameter_type] PT ON PT.[id] = AN.[parameter_type_id]
LEFT JOIN [unit] U ON U.[id] = R.[unit_id]
LEFT JOIN [analyte_fraction] ANF ON ANF.[id] = R.[analyte_fraction_id]
LEFT JOIN [organization] O1 ON O1.[id] = S.[sampler_id]
LEFT JOIN [organization] O2 ON O2.[id] = A.[lab_id]
LEFT JOIN [analysis_method] AM ON AM.[id] = A.[analysis_method_id]
CROSS APPLY
(
SELECT ' - Conc',1 UNION ALL
SELECT ' - Q',2 UNION ALL
SELECT ' - MDL' ,3 UNION ALL
SELECT ' - RL', 4 --Do not use UNION ALL on the last line
) AS c (col,so)
WHERE
P.id = 6
AND S.sample_source = 'Field'
AND AN.abbreviation in('Cd')
-- AND AN.abbreviation in('Ba', 'Cd','Se','Zr')
--Adding FOR XML PATH to the end of a query allows you to output the results of the query as XML elements, with the element name contained in the PATH argument.
FOR XML PATH,TYPE
).value('.[1]','nvarchar(max)'), 1, 1, ''
); -- END of STUFF function
--
-- Now we build the dynamic query using @cols variable where needed.
--
SET @query = '
SELECT
pvt.[EventName]
,pvt.[Location]
,pvt.[FieldSampleID]
,pvt.[DateCollected]
,'+ @cols +'
FROM
(
SELECT
ME.event_name AS [EventName]
,O2.organization_name AS [LAB]
,A.sdg AS [SDG]
,L.name_or_geocode AS [Location]
,ST.type AS [SampleType]
,A.lab_sample_ident AS [LabSampleID]
,S.sample_ident AS [FieldSampleID]
,CAST(S.monitoring_date as Date) AS [DateCollected]
--
-- The following two fields represent the pivot parameters
--
,col = AN.[abbreviation] + col
,val
FROM [project] P
INNER JOIN [monitoring_event_type] MET ON P.[id] = MET.[project_id]
INNER JOIN [monitoring_event] ME ON MET.[id] = ME.[event_type_id]
INNER JOIN [sample] S ON ME.[id] = S.[event_id]
INNER JOIN [location] L ON L.[id] = S.[location_id]
INNER JOIN [analysis] A ON A.[sample_id] = S.[id]
INNER JOIN [result] R ON R.[analysis_id] = A.[id]
INNER JOIN [result_qualifier] RQ ON RQ.[id] = R.[id]
LEFT JOIN [result_validation] RV ON RV.[id] = R.[id]
LEFT JOIN [sample_type] ST ON ST.[id] = R.[sample_type_id]
INNER JOIN [analyte] AN ON AN.[id] = R.[analyte_id]
LEFT JOIN [parameter_type] PT ON PT.[id] = AN.[parameter_type_id]
LEFT JOIN [unit] U ON U.[id] = R.[unit_id]
LEFT JOIN [analyte_fraction] ANF ON ANF.[id] = R.[analyte_fraction_id]
LEFT JOIN [organization] O1 ON O1.[id] = S.[sampler_id]
LEFT JOIN [organization] O2 ON O2.[id] = A.[lab_id]
LEFT JOIN [analysis_method] AM ON AM.[id] = A.[analysis_method_id]
CROSS APPLY
(
SELECT '' - Conc'',CAST(R.[VALUE] AS varchar(20)) UNION ALL
SELECT '' - Q'',CAST(RQ.[qualifiers] AS varchar(20)) UNION ALL
SELECT '' - MDL'',CAST(RQ.[MDL] AS varchar(20)) UNION ALL
SELECT '' - RL'',CAST(RQ.[RL] AS varchar(20)) --Do not use UNION ALL on the last line
) AS c (col,val)
WHERE
P.id = 6
AND S.sample_source = ''Field''
AND AN.abbreviation in(''Cd'')
--AND AN.abbreviation in(''Ba'', ''Cd'',''Se'',''Zr'')
) AS t
PIVOT
(
Max(t.[val])
FOR col IN ('+ @cols +')
)AS pvt
ORDER BY pvt.[EventName], pvt.[Location];
';
--
-- Execute the sql string contained in @query.
--
--Print @query
EXECUTE(@query);
--Select (@query);