简体   繁体   中英

Select data from multiple tables in SQL Server

I have 6 unique tables with same column AFFECTED_ITEM .

I want a query will which output column AFFECTED_ITEM and Count(*) for each table.

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;

Example:

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

etc..

Use a Common Table Expression to get a list of all possible values for AFFECTED_ITEM from all tables:

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
)

Then combine that with the Group By clause combine with LEFT Joins to get the counts:

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

See it demonstrated in this sql fiddle .

You could use LEFT JOIN and Count Distinct in key columns

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

Left join is not true reault you need full outer join 2 by 2 like this :

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
)

Then repeat it for next 2 tables and next two ones then full join all the results with each other. It will be a long query but you won't loose ant data for sure.

Take a look at this link : http://www.dofactory.com/sql/full-outer-join you need full join then for avoiding null values need 'coalesce', LEFT JOIN is absolutely wrong and you will loose data in right table.

First insert all your table1 , table2 ... table6 data to temp table.After that use PIVOT concept based on that temp table

  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 

Please try the following...

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

Here we left join five of the datasets returned by your six queries to the sixth query on the common value AFFECTED_ITEM (the order in which you do so does not matter in this case).

We then SELECT each row from the newly formed dataset and display each of the count fields. Coalesce is used to display a 0 where no count exists for that value of AFFECTED_ITEM .

If you have any questions or comments, then please feel free to post a Comment accordingly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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