简体   繁体   English

如何在具有多连接和子查询的查询中实现交叉表? (SQL 服务器)

[英]how to implement crosstab in query with multi join and subqueries ? (SQL Server)

How to apply crosstab in my case..如何在我的情况下应用交叉表..

I want to make the PRODUCT NAME as a columns so I can avoid duplicated records of DC_Name,Call and Register Outlet .我想将 PRODUCT NAME 作为列,这样我就可以避免DC_Name,Call 和 Register Outlet的重复记录。

and after I did some research I found that CrossTab can give me what I want.. but I don't know how to implement it to my Query.. because the Example of the Tutorials was so simple and easy..在我做了一些研究之后,我发现 CrossTab 可以给我我想要的东西.. 但我不知道如何将它实现到我的查询中.. 因为教程示例是如此简单易行..

can someone tell me how to implement it to my query..有人可以告诉我如何在我的查询中实现它..

and here is my Query:这是我的查询:

select
            dist.NM_DIST as DC_Name,
            call.Call,
            ro.RegisterOulet,
            c.NAMA_SGRUP as Product_Name,
            c.EffectiveCall
            ,f.OT as Out_Transaction
            ,c.EffectiveCall/f.ot as Ratio
            ,g.SBQ as Sales_by_qty
from assrkmd as a
inner join asscusext as ext on ext.KODE_CUS=a.KODE_CUS
inner join assdistributor as dist on dist.KD_DIST=ext.KD_DIST
inner join (
                select dis.KD_DIST,count(a.KODE_CUS ) as Call
                from assrkmd as a 
                inner join asscusext as cus on cus.KODE_CUS=a.KODE_CUS
                inner join assdistributor as dis on dis.KD_DIST=cus.KD_DIST
                where (a.TGL_RKM  between '20211101' and '20211130') and a.CHECK_OUT is not null 
                group by dis.KD_DIST
        ) as call on call.KD_DIST=dist.KD_DIST
inner join (
                select d.KD_DIST, d.NM_DIST, count(b.KODE_CUS) as RegisterOulet
                from assmds as a
                inner join asscus as b on a.KODE_SLS=b.KODE_SAL
                inner join asscusext as c on b.KODE_CUS=c.KODE_CUS
                inner join assdistributor as d on d.KD_DIST=c.KD_DIST
                group by d.KD_DIST, d.NM_DIST
        ) as RO on RO.KD_DIST=dist.KD_DIST
inner join (
            select a.KD_DIST, a.NM_DIST, a.KODE_SGRUP, a.NAMA_SGRUP, count(a.TGL_RKM) as EffectiveCall
            from ( 
                    select f.KD_DIST, f.NM_DIST, h.KODE_MDS, h.NAMA_MDS, e.KODE_CUS, g.NAMA_PT, d.KODE_SGRUP, d.NAMA_SGRUP, b.TGL_RKM
                    from assrkmdjuald as a
                    inner join assrkmdjualh as b on a.TGL_RKM=b.TGL_RKM and a.NO_NOTA=b.NO_NOTA
                    inner join asstok as c on a.KODE_BRG=c.KODE_BRG
                    inner join asssgrupbrg as d on c.KODE_SGRUP=d.KODE_SGRUP
                    inner join asscusext as e on e.KODE_CUS=b.KODE_CUS
                    inner join asscus as g on g.KODE_CUS=e.KODE_CUS
                    inner join assmds as h on h.KODE_SLS=g.KODE_SAL
                    inner join assdistributor as f on f.KD_DIST=e.KD_DIST
                    group by f.KD_DIST, f.NM_DIST, h.KODE_MDS, h.NAMA_MDS, e.KODE_CUS, g.NAMA_PT, d.KODE_SGRUP, d.NAMA_SGRUP, b.TGL_RKM
                ) as a
            where a.TGL_RKM between '20211101' and '20211130'
            group by a.KD_DIST, a.NM_DIST, a.KODE_SGRUP, a.NAMA_SGRUP
        ) as c on c.KD_DIST=ro.KD_DIST
left join (
                select ext.KD_DIST,b.KODE_SGRUP, count(b.KODE_CUS) as OT
                from asscusext as ext 
                inner join (
                                select a.KD_DIST,a.KODE_CUS,d.KODE_SGRUP
                                from asscusext as a
                                inner join assrkmd as kmd on kmd.kode_cus=a.kode_cus
                                inner join assrkmdjuald as b on b.KODE_CUS=a.KODE_CUS
                                left join asstok as c on c.KODE_BRG=b.KODE_BRG
                                inner join asssgrupbrg as d on d.KODE_SGRUP=c.KODE_SGRUP
                                where (kmd.TGL_RKM  between '20211101' and '20211130') and kmd.CHECK_OUT is not null 
                                group by a.KD_DIST,a.KODE_CUS,d.KODE_SGRUP
                        ) as b on b.KODE_CUS=ext.KODE_CUS
                group by ext.KD_DIST,b.KODE_SGRUP
        ) as f on f.KODE_SGRUP=c.KODE_SGRUP and f.KD_DIST=c.KD_DIST
left join (
                select  c.KODE_SGRUP,SUM(a.JUM_KARTON*b.FRACT+a.JUM_SATUAN)as SBQ
                from assrkmdjuald as a
                left join (select kode_brg,KODE_SGRUP,fract from asstok) as b on b.KODE_BRG=a.KODE_BRG
                inner join asssgrupbrg as c on c.KODE_SGRUP=b.KODE_SGRUP
                inner join asscusext as ext on ext.KODE_CUS=a.KODE_CUS
                inner join assdistributor as dist on dist.KD_DIST=ext.KD_DIST
                where (a.TGL_RKM  between '20211101' and '20211130')
                group by c.KODE_SGRUP
        ) as g on g.KODE_SGRUP=f.KODE_SGRUP
where (a.TGL_RKM  between '20211101' and '20211130')
group by call.Call,ro.RegisterOulet,ext.KD_DIST,dist.NM_DIST,g.SBQ,c.NAMA_SGRUP,f.ot,c.EffectiveCall
order by ext.kd_dist desc

above query gaves me this Result:上面的查询给了我这个结果:

DC_Name DC_名称 Call称呼 RegisterOutlet注册插座 Product Name产品名称 EffectiveCall有效呼叫 Transaction交易 Ratio比率 sales by qty按数量销售
DC CILACAP DC CILACAP 888 888 605 605 Single Sosis单一的Sosis 848 848 523 523 1 1 329859 329859
DC CILACAP DC CILACAP 888 888 605 605 Drink 240 ML喝 240 毫升 217 217 523 523 0 0 18298 18298
DC CIANJUR直流前朱尔 546 546 354 354 Single Sosis单一的Sosis 504 504 293 293 1 1 329859 329859
DC CIANJUR直流前朱尔 546 546 354 354 Drink 240 ML喝 240 毫升 42 42 125 125 0 0 16884 16884

that's not wanted result..那不是想要的结果..

and the result that i want it is like this (Avoid the Colspan and Rowspan of Header):我想要的结果是这样的(避免标题的 Colspan 和 Rowspan):

|     -    |  -  |      -       |     Effective Call      |     transaction         |          Ratio          |     Sales By Qty        |
|DC_Name   | Call|RegisterOutlet|Single Sosis|Drink 240 ML|Single Sosis|Drink 240 ML|Single Sosis|Drink 240 ML|Single Sosis|Drink 240 ML|
|DC CILACAP| 888 |     605      |   848      |    217     |    523     |    523     |      1     |      0      |   329859   |   18298    |
|DC CIANJUR| 546 |     354      |   504      |     42     |     293    |    125     |      1     |      0      |   329859   |   16884    |      

Please Help me out to get my desire Table (dynamic or non-dynamic its ok for me ) or maybe give me some tips and step of crossTab for query with multi join so i can follow it.请帮助我获得我想要的表(动态或非动态对我来说还可以),或者给我一些交叉表的提示和步骤,以便使用多连接进行查询,以便我可以遵循它。 **Product Name can be More than2 or Less than 2 **. **产品名称可以大于 2 或小于 2 **。

Here is your query rewrite witc much more clearer CTE (Common Table Expression):这是您的查询重写 witc 更清晰的 CTE(公用表表达式):

WITH
T_CALL AS
(
   select dis.KD_DIST, count(a.KODE_CUS ) as Call
   from   assrkmd as a 
          inner join asscusext as cus 
             on cus.KODE_CUS=a.KODE_CUS
          inner join assdistributor as dis 
             on dis.KD_DIST=cus.KD_DIST
   where  a.TGL_RKM  between '20211101' and '20211130' 
          and a.CHECK_OUT is not null 
   group by dis.KD_DIST
),
T_RO AS
(
   select d.KD_DIST, d.NM_DIST, count(b.KODE_CUS) as RegisterOulet
   from   assmds as a
          inner join asscus as b 
             on a.KODE_SLS=b.KODE_SAL
          inner join asscusext as c 
             on b.KODE_CUS=c.KODE_CUS
          inner join assdistributor as d 
          on d.KD_DIST=c.KD_DIST
   group  by d.KD_DIST, d.NM_DIST
),
T_A AS
(
   select f.KD_DIST, f.NM_DIST, h.KODE_MDS, h.NAMA_MDS, 
          e.KODE_CUS, g.NAMA_PT, d.KODE_SGRUP, d.NAMA_SGRUP, b.TGL_RKM
   from   assrkmdjuald as a
          inner join assrkmdjualh as b 
             on a.TGL_RKM=b.TGL_RKM and a.NO_NOTA=b.NO_NOTA
          inner join asstok as c 
             on a.KODE_BRG=c.KODE_BRG
          inner join asssgrupbrg as d 
             on c.KODE_SGRUP=d.KODE_SGRUP
          inner join asscusext as e 
             on e.KODE_CUS=b.KODE_CUS
          inner join asscus as g 
             on g.KODE_CUS=e.KODE_CUS
          inner join assmds as h 
             on h.KODE_SLS=g.KODE_SAL
          inner join assdistributor as f 
             on f.KD_DIST=e.KD_DIST
   group  by f.KD_DIST, f.NM_DIST, h.KODE_MDS, h.NAMA_MDS, 
          e.KODE_CUS, g.NAMA_PT, d.KODE_SGRUP, d.NAMA_SGRUP, b.TGL_RKM
),
T_C AS
(
   select a.KD_DIST, a.NM_DIST, a.KODE_SGRUP, a.NAMA_SGRUP, 
          count(a.TGL_RKM) as EffectiveCall
   from   T_A as a
   where  a.TGL_RKM between '20211101' and '20211130'
   group  by a.KD_DIST, a.NM_DIST, a.KODE_SGRUP, a.NAMA_SGRUP
),
T_B AS
(
   select a.KD_DIST,a.KODE_CUS,d.KODE_SGRUP
   from   asscusext as a
          inner join assrkmd as kmd 
             on kmd.kode_cus=a.kode_cus
          inner join assrkmdjuald as b 
             on b.KODE_CUS=a.KODE_CUS
          left join asstok as c 
             on c.KODE_BRG=b.KODE_BRG
          inner join asssgrupbrg as d 
             on d.KODE_SGRUP=c.KODE_SGRUP
   where  kmd.TGL_RKM  between '20211101' and '20211130' 
          and kmd.CHECK_OUT is not null 
   group  by a.KD_DIST,a.KODE_CUS,d.KODE_SGRUP
),
T_F AS
(
   select ext.KD_DIST, b.KODE_SGRUP, count(b.KODE_CUS) as OT
   from   asscusext as ext 
          inner join T_B as b 
             on b.KODE_CUS=ext.KODE_CUS
   group  by ext.KD_DIST,b.KODE_SGRUP
),
T_BB AS
(  
   select kode_brg, KODE_SGRUP, fract 
   from   asstok
),
T_G AS
(
   select c.KODE_SGRUP, SUM(a.JUM_KARTON * b.FRACT + a.JUM_SATUAN) as SBQ
   from   assrkmdjuald as a
          left join T_BB as b 
             on b.KODE_BRG=a.KODE_BRG
          inner join asssgrupbrg as c 
             on c.KODE_SGRUP=b.KODE_SGRUP
          inner join asscusext as ext 
             on ext.KODE_CUS=a.KODE_CUS
          inner join assdistributor as dist 
             on dist.KD_DIST=ext.KD_DIST
   where  a.TGL_RKM  between '20211101' and '20211130'
   group  by c.KODE_SGRUP
)
select dist.NM_DIST as DC_Name,
       call.Call,
       ro.RegisterOulet,
       c.NAMA_SGRUP as Product_Name,
       c.EffectiveCall,
       f.OT as Out_Transaction,
       c.EffectiveCall/f.ot as Ratio,
       g.SBQ as Sales_by_qty
from   assrkmd as a
       inner join asscusext as ext 
          on ext.KODE_CUS=a.KODE_CUS
       inner join assdistributor as dist 
          on dist.KD_DIST=ext.KD_DIST
       inner join T_CALL as call 
          on call.KD_DIST=dist.KD_DIST
       inner join T_RO as RO 
          on RO.KD_DIST=dist.KD_DIST
       inner join T_C as c 
          on c.KD_DIST=ro.KD_DIST
       left join T_F as f 
          on f.KODE_SGRUP=c.KODE_SGRUP and f.KD_DIST=c.KD_DIST
       left join T_G as g 
          on g.KODE_SGRUP=f.KODE_SGRUP
where  a.TGL_RKM  between '20211101' and '20211130'
group  by call.Call, ro.RegisterOulet, ext.KD_DIST, dist.NM_DIST,
       g.SBQ,c.NAMA_SGRUP,f.ot,c.EffectiveCall
order  by ext.kd_dist desc;

Now the only thing you have to do is to add a new CTE which integrates the four CASE statement as given above现在您唯一需要做的就是添加一个新的 CTE,它集成了上面给出的四个 CASE 语句

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM