【问题标题】:Select data from multiple tables in SQL Server从 SQL Server 中的多个表中选择数据
【发布时间】:2017-04-17 05:53:15
【问题描述】:

我有 6 个具有相同列 AFFECTED_ITEM 的唯一表。

我想要一个查询将为每个表输出列 AFFECTED_ITEMCount(*)

SELECT 
     AFFECTED_ITEM, Count(*)
FROM 
    dbo.Table1
WHERE 
    AFFECTED_ITEM IS NOT NULL
GROUP BY 
    AFFECTED_ITEM;

SELECT 
    AFFECTED_ITEM, Count(*)
FROM 
    dbo.Table2
WHERE 
    AFFECTED_ITEM IS NOT NULL
GROUP BY 
    AFFECTED_ITEM;

...

SELECT 
    AFFECTED_ITEM, Count(*)
FROM 
    dbo.Table6
WHERE 
    AFFECTED_ITEM IS NOT NULL
GROUP BY 
    AFFECTED_ITEM;

例子:

AFFECTED_ITEM | Table1 | Table2 | Table3 | Table6 |
--------------------------------------------------
Item1         |  53    |   45   |   12   |   0    |
Item2         |   4    |   13   |   77   |   9    |
Item3         |   7    |    0   |   24   |   23   |

等等。

【问题讨论】:

  • ,提供你的6个表的样本数据和预期的输出。

标签: sql sql-server select count


【解决方案1】:

使用Common Table Expression 从所有表中获取AFFECTED_ITEM 的所有可能值的列表:

WITH AffectedItems (AFFECTED_ITEM) AS (
  SELECT DISTINCT AFFECTED_ITEM  FROM table1
  UNION
  SELECT DISTINCT AFFECTED_ITEM  FROM table2
  UNION
  SELECT DISTINCT AFFECTED_ITEM   FROM table3
  UNION
  SELECT DISTINCT AFFECTED_ITEM   FROM table4
  UNION
  SELECT DISTINCT AFFECTED_ITEM   FROM table5
  UNION
  SELECT DISTINCT AFFECTED_ITEM   FROM table6
)

然后将其与Group By 子句结合LEFT Joins 以获取计数:

WITH AffectedItems (AFFECTED_ITEM) AS (
  SELECT DISTINCT AFFECTED_ITEM  FROM table1
  UNION
  SELECT DISTINCT AFFECTED_ITEM  FROM table2
  UNION
  SELECT DISTINCT AFFECTED_ITEM   FROM table3
  UNION
  SELECT DISTINCT AFFECTED_ITEM   FROM table4
  UNION
  SELECT DISTINCT AFFECTED_ITEM   FROM table5
  UNION
  SELECT DISTINCT AFFECTED_ITEM   FROM table6
)
SELECT ai.AFFECTED_ITEM, count(t1.name) as table1, count(t2.name) as table2, 
count(t3.name) as table3,count(t4.name) as table4, count(t5.name) as table5, 
count(t6.name) as table6
FROM AffectedItems ai
LEFT JOIN dbo.table1 t1 on t1.AFFECTED_ITEM = ai.AFFECTED_ITEM
LEFT JOIN dbo.table2 t2 on t2.AFFECTED_ITEM = ai.AFFECTED_ITEM
LEFT JOIN dbo.table3 t3 on t3.AFFECTED_ITEM = ai.AFFECTED_ITEM
LEFT JOIN dbo.table1 t4 on t4.AFFECTED_ITEM = ai.AFFECTED_ITEM
LEFT JOIN dbo.table2 t5 on t5.AFFECTED_ITEM = ai.AFFECTED_ITEM
LEFT JOIN dbo.table3 t6 on t6.AFFECTED_ITEM = ai.AFFECTED_ITEM
GROUP BY ai.AFFECTED_ITEM

sql fiddle 中看到它的演示。

【讨论】:

    【解决方案2】:

    您可以在关键列中使用LEFT JOINCount Distinct

    SELECT t.AFFECTED_ITEM, 
        Count(DISTINCT t1.KeyId ) AS Table1,
        Count(DISTINCT t2.KeyId ) AS Table2,
        Count(DISTINCT t3.KeyId ) AS Table3,
        Count(DISTINCT t4.KeyId ) AS Table4,
        Count(DISTINCT t5.KeyId ) AS Table5,
        Count(DISTINCT t6.KeyId ) AS Table6
    
    FROM yourTable t
    LEFT JOIN Table1 t1 ON t.AFFECTED_ITEM = t1.AFFECTED_ITEM
    LEFT JOIN Table2 t2 ON t.AFFECTED_ITEM = t2.AFFECTED_ITEM
    LEFT JOIN Table3 t3 ON t.AFFECTED_ITEM = t3.AFFECTED_ITEM
    LEFT JOIN Table4 t4 ON t.AFFECTED_ITEM = t4.AFFECTED_ITEM
    LEFT JOIN Table5 t5 ON t.AFFECTED_ITEM = t5.AFFECTED_ITEM
    LEFT JOIN Table6 t6 ON t.AFFECTED_ITEM = t6.AFFECTED_ITEM
    
    GROUP BY t.AFFECTED_ITEM
    

    【讨论】:

    • 我有一个错误 Ambiguous column name 'AFFECTED_ITEM'
    【解决方案3】:

    左连接不是真正的 reault,您需要像这样 2×2 完全外连接:

    with CteT1AndT2 as (
     SELECT  coalesce(t1.AFFECTED_ITEM,t2.AFFECTED_ITEM) as AFFECTED_ITEM, 
        Count(DISTINCT t1.KeyId ) AS CntTable1,
        Count(DISTINCT t2.KeyId ) AS CntTable2,
    
       FROM  Table1 t1 
         FULL OUTER JOIN Table2 ON t1.AFFECTED_ITEM = t2.AFFECTED_ITEM
        GROUP BY t1.AFFECTED_ITEM,t2.AFFECTED_ITEM
    )
    

    然后对接下来的 2 个表和接下来的两个表重复此操作,然后将所有结果完全连接在一起。这将是一个很长的查询,但您肯定不会丢失 ant 数据。

    看看这个链接:http://www.dofactory.com/sql/full-outer-join 你需要完全连接,然后为了避免空值需要'coalesce',左连接是绝对错误的,你会丢失右表中的数据。

    【讨论】:

      【解决方案4】:

      首先将所有 table1 , table2 ... table6 数据插入临时表。然后使用基于该临时表的 PIVOT 概念

        CREATE TABLE #table(AFFECTED_ITEM VARCHAR(100),_Count INT,_table 
        VARCHAR(100))
      
        INSERT INTO #table(AFFECTED_ITEM ,_Count , _table )
        SELECT AFFECTED_ITEM, Count(*),'Table1'
        FROM dbo.Table1
        WHERE AFFECTED_ITEM IS NOT NULL
        GROUP BY AFFECTED_ITEM 
      
        INSERT INTO #table(AFFECTED_ITEM ,_Count , _table )
        SELECT AFFECTED_ITEM, Count(*),'Table2'
        FROM dbo.Table2
        WHERE AFFECTED_ITEM IS NOT NULL
        GROUP BY AFFECTED_ITEM 
      
        .......  Upto table6 
      
      
        SELECT AFFECTED_ITEM , ISNULL([Table1],0) [Table1] , ISNULL([Table2],0) 
        [Table2] , ISNULL([Table3],0) [Table3] , ISNULL([Table4],0) [Table4] , 
        ISNULL([Table5],0) [Table5],ISNULL([Table6],0) [Table6]
        FROM 
        (
           SELECT AFFECTED_ITEM , _Count , _table     
           FROM #table
        ) A
        PIVOT
       (
         SUM(_Count) FOR _table IN ([Table1],[Table2],[Table3],[Table4],[Table5],
         [Table6])
       ) pvt 
      

      【讨论】:

      • @Keilash,我为你的问题发布了答案。试试上面的查询。
      【解决方案5】:

      请尝试以下...

      SELECT itemCountFinder1.AFFECTED_ITEM AS AFFECTED_ITEM,
             COALESCE( itemCount1, 0 ) AS Table1,
             COALESCE( itemCount2, 0 ) AS Table2,
             COALESCE( itemCount3, 0 ) AS Table3,
             COALESCE( itemCount4, 0 ) AS Table4,
             COALESCE( itemCount5, 0 ) AS Table5,
             COALESCE( itemCount6, 0 ) AS Table6
      FROM ( SELECT AFFECTED_ITEM,
                    Count( * ) AS itemCount1
             FROM dbo.Table1
             WHERE AFFECTED_ITEM IS NOT NULL
             GROUP BY AFFECTED_ITEM ) AS itemCountFinder1
      LEFT JOIN ( SELECT AFFECTED_ITEM,
                         Count( * ) AS  AS itemCount2
                  FROM dbo.Table2
                  WHERE AFFECTED_ITEM IS NOT NULL
                  GROUP BY AFFECTED_ITEM ) AS itemCountFinder2 ON itemCountFinder1.AFFECTED_ITEM = itemCountFinder2.AFFECTED_ITEM
      LEFT JOIN ( SELECT AFFECTED_ITEM,
                         Count( * ) AS itemCount3
                  FROM dbo.Table3
                  WHERE AFFECTED_ITEM IS NOT NULL
                  GROUP BY AFFECTED_ITEM ) AS itemCountFinder3 ON itemCountFinder1.AFFECTED_ITEM = itemCountFinder3.AFFECTED_ITEM
      LEFT JOIN ( SELECT AFFECTED_ITEM,
                         Count( * ) AS itemCount4
                  FROM dbo.Table4
                  WHERE AFFECTED_ITEM IS NOT NULL
                  GROUP BY AFFECTED_ITEM ) AS itemCountFinder4 ON itemCountFinder1.AFFECTED_ITEM = itemCountFinder4.AFFECTED_ITEM
      LEFT JOIN ( SELECT AFFECTED_ITEM,
                         Count( * ) AS itemCount5
                  FROM dbo.Table5
                  WHERE AFFECTED_ITEM IS NOT NULL
                  GROUP BY AFFECTED_ITEM ) AS itemCountFinder5 ON itemCountFinder1.AFFECTED_ITEM = itemCountFinder5.AFFECTED_ITEM
      LEFT JOIN ( SELECT AFFECTED_ITEM,
                         Count( * ) AS itemCount6
                  FROM dbo.Table6
                  WHERE AFFECTED_ITEM IS NOT NULL
                  GROUP BY AFFECTED_ITEM ) AS itemCountFinder6 ON itemCountFinder1.AFFECTED_ITEM = itemCountFinder6.AFFECTED_ITEM
      

      在这里,我们将您的六个查询返回的五个数据集与公共值 AFFECTED_ITEM 的第六个查询进行连接(在这种情况下,您执行此操作的顺序无关紧要)。

      然后我们SELECT 来自新形成的数据集的每一行并显示每个计数字段。 Coalesce 用于显示0,其中AFFECTED_ITEM 的值不存在计数。

      如果您有任何问题或cmets,请随时发表相应的评论。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-08-15
        • 2012-12-22
        • 1970-01-01
        • 2021-02-06
        • 1970-01-01
        • 1970-01-01
        • 2013-07-25
        相关资源
        最近更新 更多