简体   繁体   中英

I need a specific output

I have to get a specific output format from my tables.

Let's say I have a simple table with 2 columns name and value .

table T1

+---------------+------------------+
| Name          | Value            |
+---------------+------------------+
| stuff1        | 1                |
| stuff1        | 1                |
| stuff2        | 2                |
| stuff3        | 1                |
| stuff2        | 4                |
| stuff2        | 2                |
| stuff3        | 4                | 
+---------------+------------------+

I know the values are in the interval 1-4. I group it by name and value and count number of the same rows as Number and get the following table:

table T2

+---------------+------------------+--------+
| Name          | Value            | Number |
+---------------+------------------+--------+
| stuff1        | 1                | 2      |
| stuff2        | 2                | 2      |
| stuff3        | 1                | 1      |
| stuff3        | 4                | 1      |
+---------------+------------------+--------+

Here is the part when I need your help! What should I do if I want to get these format?

table T3

+---------------+------------------+--------+
| Name          | Value            | Number |
+---------------+------------------+--------+
| stuff1        | 1                | 2      |
| stuff1        | 2                | 0      |
| stuff1        | 3                | 0      |
| stuff1        | 4                | 0      |
| stuff2        | 1                | 0      |
| stuff2        | 2                | 2      |
| stuff2        | 3                | 0      |
| stuff2        | 4                | 0      |
| stuff3        | 1                | 1      |
| stuff3        | 2                | 0      |
| stuff3        | 3                | 0      |
| stuff3        | 4                | 1      |
+---------------+------------------+--------+

Thanks for any suggestions!

You start with a cross join to generate all possible combinations and then left-join in the results from your existing query:

select n.name, v.value, coalesce(nv.cnt, 0) as "Number"
from (select distinct name from table t) n cross join
     (select distinct value from table t) v left outer join
     (select name, value, count(*) as cnt
      from table t
      group by name, value
     ) nv
     on nv.name = n.name and nv.value = v.value;

Variation on the theme.

Differences between Gordon Linoff and Owen existing answers.

  1. I prefer GROUP BY to get the Names rather than a DISTINCT. This may have better performance in a case like this. (See Rob Farley's still relevant article .)
  2. I explode the subqueries into a series of CTEs for clarity.
  3. I use table T2 as the question now labels the group results set instead of showing that as as subquery.

     WITH PossibleValue AS ( SELECT 1 Value UNION ALL SELECT Value + 1 FROM PossibleValue WHERE Value < 4 ), Name AS ( SELECT Name FROM T1 GROUP BY Name ), NameValue AS ( SELECT Name ,Value FROM Name CROSS JOIN PossibleValue ) SELECT nv.Name ,nv.Value ,ISNULL(T2.Number,0) Number FROM NameValue nv LEFT JOIN T2 ON nv.Name = T2.Name AND nv.Value = T2.Value 

Yet another solution, this time using a Table Value Constructor in a CTE to build a table of name value combinations.

WITH value AS 
( SELECT DISTINCT t.name, v.value
    FROM T1 AS t
   CROSS JOIN (VALUES (1),(2),(3),(4)) AS v (value)
)
  SELECT v.name AS 'Name', v.value AS 'Value', COUNT(t.name) AS 'Number'
    FROM value AS v
    LEFT JOIN T1 AS t ON t.value = v.value AND t.name = v.name
GROUP BY v.name, v.value, t.name;

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