SQL查询-动态列将不会按照SO排序

时间:2018-11-08 18:24:22

标签: sql sql-server ssms

我创建了一个透视查询,希望交叉应用的动态“列”以特定方式排序,而不会。

这是如何返回动态“列”的方式: [Cd-Conc] [Cd-RL] [Cd-Q] [Cd-MDL]

这是我希望他们返回的方式: [Cd-Conc] [Cd-Q] [Cd-MDL] [Cd-RL]

虽然我尝试如上所述获得排序顺序,但查询仅限于一种分析物“ Cd”,但不一定知道分析物的总数。我希望它们按分析物的浓度,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);          

1 个答案:

答案 0 :(得分:0)

在创建SO的查询中,在ORDER BY中使用@cols列。