- Home /

There are an interesting query problem I am facing. I am trying solve using single query, opposite to use of temporary tables or string concatenation functions.

Basically, I have Table “T” with an integer id and 6 populated columns A, B, C, D, E, F with integer values. I have to populate columns A1, A2, A3, A4, A5, A6 where:

A1 value should be populated with the number of occurrences of value in the field A over fields A, B, C, D, E, F in the same row

B1 value should be populated with the number of occurrences of value in the field B over fields A, B, C, D, E, F in the same row

Etc…

Sample of values with calculated values for A1, A2, A3, A4, A5, A6 after running a query should be:

sample.png
(9.6 KiB)

Comment

**Answer** by Jeff Moden ·

First of all, the graphic is great for showing what you want to end up with but... it would also be incredibly helpful if you posted "Readily Consumable" data in the future to help those trying to help you, especially those of us that like to test our solutions before we post them.

Here's one way you could have done that for this post.

SELECT IntID = IDENTITY(INT,1,1) ,A,B,C,D,E,F INTO #TestTable FROM (VALUES (0,0,2,2,3,3) ,(0,2,2,2,3,1) ,(3,4,1,3,1,2) ,(3,0,0,1,1,3) ,(0,4,1,2,3,3) )v(A,B,C,D,E,F) ;

In anticipation of making it a bit easier to add or remove column in the future, here's a bit of code that is pretty easy to do so with.

WITH CTE AS (--==== Unpivot and count SELECT * ,RowValCnt = COUNT(*) OVER (PARTITION BY IntID,Val) FROM (SELECT IntID,A,B,C,D,E,F FROM #TestTable) t UNPIVOT (Val FOR Col IN (A,B,C,D,E,F))unpvt )--==== Repivot using a CROSSTAB, which simply displays the pivoted answer. SELECT IntID ,A = MAX(CASE WHEN Col = 'A' THEN Val END) ,B = MAX(CASE WHEN Col = 'B' THEN Val END) ,C = MAX(CASE WHEN Col = 'C' THEN Val END) ,D = MAX(CASE WHEN Col = 'D' THEN Val END) ,E = MAX(CASE WHEN Col = 'E' THEN Val END) ,F = MAX(CASE WHEN Col = 'F' THEN Val END) ,A1 = MAX(CASE WHEN Col = 'A' THEN RowValCnt END) ,B1 = MAX(CASE WHEN Col = 'B' THEN RowValCnt END) ,C1 = MAX(CASE WHEN Col = 'C' THEN RowValCnt END) ,D1 = MAX(CASE WHEN Col = 'D' THEN RowValCnt END) ,E1 = MAX(CASE WHEN Col = 'E' THEN RowValCnt END) ,F1 = MAX(CASE WHEN Col = 'F' THEN RowValCnt END) FROM CTE GROUP BY IntID ;

Here are the results...

zkx4g.png
(5.5 KiB)

**Answer** by Oleg ·

This problem is actually pretty simple, except that the question description is somewhat confusing. There is a request to populate columns** A1, A2, A3, A4, A5, A6**, while the image displays columns named **A1, B1, C1, D1, E1** and **F1**. The explanation of the requirement mentions columns **A1, B1**, etc. It would be best to ask the question accurately enough as not to cause any ambiguity in what actually needs to be done.

Assuming that there are no NULL values in any of the columns, one possible solution is to simply compare every column value to the value in the given column and sum up if the values are the same. Since the value in any of the columns is always going to be equal to itself, the smallest resulting value in columns A1, B1, C1, D1, E1 and F1 (I picked this one from the available combinations) is going to be 1 while the maximum value is 6 (because there are 6 columns). Here is the script which will work as expected:

select A, B, C, D, E, F, 1 + case when A = B then 1 else 0 end + case when A = C then 1 else 0 end + case when A = D then 1 else 0 end + case when A = E then 1 else 0 end + case when A = F then 1 else 0 end A1, case when B = A then 1 else 0 end + 1 + case when B = C then 1 else 0 end + case when B = D then 1 else 0 end + case when B = E then 1 else 0 end + case when B = F then 1 else 0 end B1, case when C = A then 1 else 0 end + case when C = B then 1 else 0 end + 1 + case when C = D then 1 else 0 end + case when C = E then 1 else 0 end + case when C = F then 1 else 0 end C1, case when D = A then 1 else 0 end + case when D = B then 1 else 0 end + case when D = C then 1 else 0 end + 1 + case when D = E then 1 else 0 end + case when D = F then 1 else 0 end D1, case when E = A then 1 else 0 end + case when E = B then 1 else 0 end + case when E = C then 1 else 0 end + case when E = D then 1 else 0 end + 1 + case when E = F then 1 else 0 end E1, case when F = A then 1 else 0 end + case when F = B then 1 else 0 end + case when F = C then 1 else 0 end + case when F = D then 1 else 0 end + case when F = E then 1 else 0 end + 1 F1 from YourTable

Using the sample data in question, the query produces the following output:

A B C D E F A1 B1 C1 D1 E1 F1 ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 0 0 2 2 3 3 2 2 2 2 2 2 0 2 2 2 3 1 1 3 3 3 1 1 3 4 1 3 1 2 2 1 2 2 2 1 3 0 0 1 1 3 2 2 2 2 2 2 0 4 1 2 3 3 1 1 1 1 2 2

Hope this helps.

Oleg

Copyright 2019 Redgate Software.
Privacy Policy

- Anonymous
- Sign in
- Create
- Ask a question
- Spaces
- Site Issues (NOT FOR DATABASE QUESTIONS)
- Explore
- Topics
- Questions
- Users
- Badges