0

I have the table xyz

ID    day1    day2    day3    day4
1     A         A       P       P
2     A         A       A       P
3     A         A       A       A
4     A         P       P       P

I want to be able to query this and return the ID with the number of columns that have A as their value in that row. So the result would look like this:

ID    Count
 1     2
 2     3
 3     4
 4     1
3
  • 2
    How many columns do you have in actual ? Commented May 22, 2018 at 5:56
  • 1
    Any SQL attempts from your side should be posted Commented May 22, 2018 at 5:58
  • So you want to pass a value (in this case A) as a condition to your query? Commented May 22, 2018 at 6:11

2 Answers 2

3

Here is a trick you can use involving string concatenation:

SELECT
    ID,
    CHAR_LENGTH(CONCAT(day1, day2, day3, day4)) -
    CHAR_LENGTH(REPLACE(CONCAT(day1, day2, day3, day4), 'A', '')) AS Count
FROM yourTable
ORDER BY ID;

enter image description here

Demo

If you want to count other letters as well, just duplicate the logic I have for the letter A, e.g. for L we can try:

CHAR_LENGTH(CONCAT(day1, day2, day3, day4)) -
CHAR_LENGTH(REPLACE(CONCAT(day1, day2, day3, day4), 'L', ''))
Sign up to request clarification or add additional context in comments.

6 Comments

I think it would be good to place concatenation in subquery and use its results multiple times in outer query. Wouldn't it be more efficient? IMO, it would look cleaner and more concise I guess :)
@MichałTurczyn I have no idea what you mean. The replacement would have to be run separately for each letter, there is no way around this that I can see (short of writing a UDF).
Well, doing it the way you suggested, you have to invoke concatenation 2 times for each letter. Doing it in a subquery would result in invoking CONCAT method once. But I definietely agree that is correct query to get the desired results :) +1
@MichałTurczyn I see no reason to use a subquery here, whose overhead would likely greatly outweigh any savings you are suggesting.
Just to be clear: select char_length(concat(...)) - char_length(concat(...)) from tbl compared to select char_length(col) - char_length(replace(col)) from (select concat(...) as col from tbl) as innerTbl.
|
2

This is simple to accomplish applying case to all columns and usmming them up! Try below:

select id,
       case day1 when 'A' then 1 else 0 end +
       case day2 when 'A' then 1 else 0 end +
       case day3 when 'A' then 1 else 0 end +
       case day4 when 'A' then 1 else 0 end `CountA`,
       case day1 when 'L' then 1 else 0 end +
       case day2 when 'L' then 1 else 0 end +
       case day3 when 'L' then 1 else 0 end +
       case day4 when 'L' then 1 else 0 end `CountL`,
       case day1 when 'P' then 1 else 0 end +
       case day2 when 'P' then 1 else 0 end +
       case day3 when 'P' then 1 else 0 end +
       case day4 when 'P' then 1 else 0 end `CountP`
from Tbl

5 Comments

Thanks Michal .I Also the number of columns that have A L and P as their value in that row
@karansharma See updated answer :) Also accept it, if it solved the rpoblem.
@TimBiegeleisen I suppose that I filled all OPs requests, but you are totally right and that's why I used if statement :)
Thanks Michal Its Woks
@karansharma You have to valid answers, you should accept one of them :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.