【问题标题】:Concact Multiple SQL Rows where Preceding Columns are the Same with Table Joins连接多个 SQL 行,其中前面的列与表连接相同
【发布时间】:2019-11-21 03:05:52
【问题描述】:

我有以下 SQL 查询:

SELECT stock_items.stockcode, 
   x_apvma_product.pcode, 
   x_apvma_product.fpname, 
   x_apvma_product.sname, 
   x_apvma_host.hostdesc, 
   x_apvma_pest.pestdesc
FROM   x_apvma_product 
   INNER JOIN stock_items 
           ON stock_items.x_apvma_product_no = x_apvma_product.pcode 
   INNER JOIN x_apvma_product_use 
           ON x_apvma_product_use.pcode = x_apvma_product.pcode 
   LEFT OUTER JOIN x_apvma_host 
                ON x_apvma_host.hostcode = x_apvma_product_use.hostcode 
   LEFT OUTER JOIN x_apvma_pest 
                ON x_apvma_pest.pestcode = x_apvma_product_use.pestcode
WHERE  x_apvma_product.pcode IN (SELECT x_apvma_product_no 
                             FROM   stock_items) 
   AND stock_items.web_show = 'Y'; 

哪个结果(从一个库存项目中选择结果,因为整个查询有超过 74k 行):

stockcode   pcode   fpname                          sname                       hostdesc                        pestdesc
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   POTTING MIX, COMPOST, MANURE    FUNGUS GNAT
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   POTTING MIX, COMPOST, MANURE    SHORE FLY
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   AZALEA                          AZALEA LACE BUG
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   MARIGOLD                        YELLOW LEAFHOPPER
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   MARIGOLD                        LEAFHOPPER
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   ORCHID                          CITRUS MEALY BUG
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   ORNAMENTAL PLANT                CITRUS MEALY BUG
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   PALM                            CITRUS MEALY BUG
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   GERBERA GREENHOUSE              WHITEFLY
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   ORNAMENTAL PLANT                GREENHOUSE WHITEFLY
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   FUCHSIA GREENHOUSE              WHITEFLY
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   GERBERA SILVERLEAF              WHITEFLY
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   ORNAMENTAL PLANT                SILVERLEAF WHITEFLY
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   FUCHSIA SILVERLEAF              WHITEFLY
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   ORNAMENTAL PLANT                SCALE INSECTS
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   ROSE                            ROSE APHID
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   ORNAMENTAL PLANT                PLAGUE THRIPS
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   MARIGOLD                        VEGETABLE LEAFHOPPER
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   LILLY PILLY                     PSYLLID OR LERP INSECT
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   ORNAMENTAL PLANT                GREEN COFFEE SCALE
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   ORNAMENTAL PLANT                PULVINARIA SCALE
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   AZALEA                          GREENHOUSE THRIP
9075    58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   ORNAMENTAL PLANT                NIGRA SCALE

如何更改查询,以便获得多个 x_apvma_host.hostdesc 的 1 行并将 x_apvma_pest.pestdesc 的多个结果连接成一个,用逗号分隔?当然,这需要每个股票代码。

结果应该是:

Stockcode   Pcode   Fpname                              Sname                       Hostdesc                        pestconcat
9075        58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   Azalea                          Azalea Lace Bug, Greenhouse Thrip
9075        58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   Fuchsia                         Greenhouse Whitefly, Silverleaf Whitefly
9075        58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   Gerbera                         Greenhouse Whitefly, Silverleaf Whitefly
9075        58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   Lilly Pilly                     Psyllid Or Lerp Insect
9075        58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   Marigold                        Leafhopper, Vegetable Leafhopper, Yellow Leafhopper
9075        58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   Orchid                          Citrus Mealy Bug
9075        58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   Ornamental Plant                Citrus Mealy Bug, Green Coffee Scale, Greenhouse Whitefly, Nigra Scale, Plague Thrips, Pulvinaria Scale, Scale Insects, Silverleaf Whitefly
9075        58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   Palm                            Citrus Mealy Bug
9075        58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   Potting Mix, Compost, Manure    Fungus Gnat, Shore Fly
9075        58558   CROWN 225SL SYSTEMIC INSECTICIDE    EVERRIS AUSTRALIA PTY LTD   Rose                            Rose Aphid

我知道您可以使用 STUFFFOR XML PATH 函数,但是我发现的所有教程都更简单,并且不涉及连接表,到目前为止我还没有弄清楚如何在我的情况下使用这些并获得正确的结果。

这里有一些测试数据 - http://sqlfiddle.com/#!9/b3f4e3/1/0

【问题讨论】:

    标签: sql sql-server concatenation


    【解决方案1】:

    请尝试使用示例数据添加SQL Fiddle Link

    您可以尝试以下方法:

    编辑:在添加 sql fiddle 后更新查询。

    ;WITH CTE AS
    (
        SELECT DISTINCT stock_items.stockcode,
               x_apvma_product.pcode,
               x_apvma_product.fpname,
               x_apvma_product.sname,
               x_apvma_host.hostdesc,
               x_apvma_pest.pestdesc
        FROM   x_apvma_product
               INNER JOIN stock_items
                       ON stock_items.x_apvma_product_no = x_apvma_product.pcode
               INNER JOIN x_apvma_product_use
                       ON x_apvma_product_use.pcode = x_apvma_product.pcode
               LEFT OUTER JOIN x_apvma_host
                            ON x_apvma_host.hostcode = x_apvma_product_use.hostcode
               LEFT OUTER JOIN x_apvma_pest
                            ON x_apvma_pest.pestcode = x_apvma_product_use.pestcode
        WHERE stock_items.web_show = 'Y'
    ) 
    SELECT DISTINCT 
            stockcode,
            pcode,
            fpname,
            sname,
            hostdesc,
            pestdesc = STUFF((SELECT DISTINCT ','+pestdesc  
                              FROM CTE c 
                              WHERE c.hostdesc = c2.hostdesc 
                              FOR XML PATH('')),1,1,'')
    FROM CTE c2
    

    也不需要条件x_apvma_product.pcode IN (SELECT x_apvma_product_no FROM stock_items),因为这些表之间已经有JOIN

    SQL Fiddle

    【讨论】:

    • 谢谢@MAK - 我认为我们已经接近这个了,我在运行Msg 8120, Level 16, State 1, Line 6 Column 'x_apvma_product_use.pestcode' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause 时遇到错误但是如果我将它添加到 group by 子句中,我得到的结果与我在我的问题中的第一个查询......?抱歉,答案可能很明显,但我还在学习!
    • 更改为 DISTINCT 仍然可以解决与我的初始查询相同的结果。在FOR XML PATH('')) 之后也需要一个逗号
    • @DaleP,请添加一些示例数据的 SQL Fiddle 链接。
    • @DaleP,我添加了 SQL Fiddle 链接,请查看我的答案。
    • 那不起作用...我终于在 SQLFiddle 中设置了一些真实数据-抱歉延迟-sqlfiddle.com/#!9/b3f4e3/1/0-是的,它确实需要x_apvma_product.pcode IN (SELECT x_apvma_product_no FROM stock_items) ,因为它是从一张大表中绘制的有很多与我们的库存项目无关的数据......所以where 子句大大减少了返回结果的数量,只返回相关的结果。
    【解决方案2】:

    您可以更改您的LEFT OUTER JOIN x_apvma_host

    LEFT OUTER JOIN (select x,y from x_apvma_host group by x,y) x_apvma_host

    参考:

    https://www.w3schools.com/sql/sql_groupby.asp

    【讨论】:

      【解决方案3】:

      另一个运行速度更快的解决方案是:

      SELECT DISTINCT stock_items.stockcode [sku],
                 x_apvma_product.pcode,
                 x_apvma_product.fpname,
                 x_apvma_product.sname,
                 x_apvma_host.hostdesc,
                 x_apvma_pest.pestdesc
                 into #TEMP_APVMA_Table
          FROM   x_apvma_product
                 INNER JOIN stock_items
                         ON stock_items.x_apvma_product_no = x_apvma_product.pcode
                 INNER JOIN x_apvma_product_use
                         ON x_apvma_product_use.pcode = x_apvma_product.pcode
                 LEFT OUTER JOIN x_apvma_host
                              ON x_apvma_host.hostcode = x_apvma_product_use.hostcode
                 LEFT OUTER JOIN x_apvma_pest
                              ON x_apvma_pest.pestcode = x_apvma_product_use.pestcode
          WHERE stock_items.web_show = 'Y'
       ;
      SELECT DISTINCT 
              sku,
              hostdesc,
              pestdesc = STUFF((SELECT DISTINCT ','+pestdesc  
                                FROM #TEMP_APVMA_Table c 
                                WHERE c.hostdesc = c2.hostdesc 
                                AND c.sku = c2.sku
                                FOR XML PATH('')),1,1,'')
      FROM #TEMP_APVMA_Table c2
      

      【讨论】:

        猜你喜欢
        • 2021-07-08
        • 2013-05-11
        • 2015-10-05
        • 2012-06-02
        • 1970-01-01
        • 1970-01-01
        • 2010-09-25
        • 2015-09-18
        • 1970-01-01
        相关资源
        最近更新 更多