0

Here is my table Here is my table

I would like to select as below The selection I would like to have

The tch_col will get the column name which column value is not 0 and if it's all 0 give the value as 19.

Could we do this is in SQL?

pls check lane 97 here enter image description here

the result should enter image description here

The first answer maybe not works but still Thank you

Joker
  • 1
  • 3
  • I removed the incompatible database tags. Please tag with the database you are actually using. – Gordon Linoff Oct 21 '16 at 20:13
  • 2
    You would be FAR better off normalizing this. Repeating groups like this is a huge red flag that your normalization is less than optimal. – Sean Lange Oct 21 '16 at 20:14
  • http://meta.stackoverflow.com/questions/285551/why-may-i-not-upload-images-of-code-on-so-when-asking-a-question/285557#285557 –  Oct 21 '16 at 20:16
  • Thank you very much for remove. This is old DB I cant not changing. I have been trapped here for 1 day!!! – Joker Oct 21 '16 at 20:16
  • If you simply want the first column that has a value > 0 you could use a case expression. – Sean Lange Oct 21 '16 at 20:16
  • There seems to be no unique key in the table. This is problematic, as there is no natural order in SQL. A SELECT query might return the rows in any order if there is no ORDER BY statement. You cannot rely on a physical line number. I would perform the logic in code, not in SQL. – Olivier Jacot-Descombes Oct 21 '16 at 20:18
  • 1
    Give UNPIVOT a try. http://stackoverflow.com/questions/19055902/unpivot-with-column-name – Isaac Oct 21 '16 at 20:18
  • @OlivierJacot-Descombes while your statement is accurate I don't understand what it has to do with this question. – Sean Lange Oct 21 '16 at 20:19
  • is not first column value, I need the column name last two dig numbers.AL SO thank you @a_horse_with_no_name – Joker Oct 21 '16 at 20:19
  • There is PK in table but i don't think it's help. – Joker Oct 21 '16 at 20:21
  • @Joker WHICH DBMS are you using? The query will not be the same for all of them. – Sean Lange Oct 21 '16 at 20:22
  • It is a problem if you want the result to have a determined order, as `ORDER BY tch_function, tch_part` is ambiguous (there are duplicates). – Olivier Jacot-Descombes Oct 21 '16 at 20:23
  • I agree but I don't see where the OP is asking anything about the order of the result set. In fact, the desired result has no apparent order to it. – Sean Lange Oct 21 '16 at 20:24

2 Answers2

1

From discussion in comments: this is for SQL Server; so using a view to create the 19 column followed by the UNPIVOT operator should simplify things.

Original answer for standard SQL follows for posterity:

You can get the result you describe (with most major SQL databases; if you're using something old or obscure this may not work).

But it's not quite as pretty as selecting the column name. The following SQL is dependent on which specific columns are in the table; see notes afterward.

If you need a record for every non-0 value, it's going to be quite bad.

SELECT tch_function, tch_part, 9
  FROM your_table
 WHERE tch_col_09 <> 0
UNION ALL
SELECT tch_function, tch_part, 10
  FROM your_table
 WHERE tch_col_10 <> 0
-- you can see where this is going, right?
-- union in another select for each column

The problem here is that standard SQL isn't good about creating an undetermined number of result rows from each input row, other than during a join.

Now if you can get your hands on a relation with a single column containing the numbers from 9 through 19, you could do a cross join with that and then filter out the rows you don't want (WHERE (your_table.tch_col_09<>0 AND ref.value=9) OR ... OR (your_table.tch_col_09=0 AND ... AND your_table.tch_col_18=0 AND ref.value=19)); but it's still cumbersome, isn't it? You could use a DB2 VALUES subquery, or a temp table, or whatever to get such a relation if you decide to go that route...

If you could assume that only one column has a non-0 value, or if you'd be happy with just the name of the column containing the first non-0 value, it'd be less ugly:

SELECT tch_function
     , tch_part
     , case when tch_col_09 <> 0 then 9
            when tch_col_10 <> 0 then 10
            when tch_col_11 <> 0 then 11
            when tch_col_12 <> 0 then 12
            when tch_col_13 <> 0 then 13
            when tch_col_14 <> 0 then 14
            when tch_col_15 <> 0 then 15
            when tch_col_16 <> 0 then 16
            when tch_col_17 <> 0 then 17
            when tch_col_18 <> 0 then 18
            else 19
       end as tch_col
  from your_table

The case structure will return the value for the first matching THEN clause, or 19 if none of the THEN clauses match.

But it sounds like that won't do.

Lastly - Any of these queries would have to change if the set of TCH_COL_n columns in the table were to change; at a minimum a good relational table structure should lead to a fairly static set of columns.

More to the point, if you could change your table structure or use a processing language other than SQL you'd be in better shape.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • (And even if the set of columns IS completely static, it's still questionable whether this is a good relational form for the data; can't say for sure without more details, but assuming the structure is what it is, the answer should work.) – Mark Adelsberger Oct 21 '16 at 20:29
  • You can try out @Mark Adelsberger 's answer here: http://sqlfiddle.com/#!9/20286/1/2 – Stavr00 Oct 21 '16 at 20:29
  • Thank you for your answer. But, for example – Joker Oct 21 '16 at 20:30
  • If tch_col_09 and tch_col_10 they both have values and it will be shown in two records in results. your way may not works – Joker Oct 21 '16 at 20:33
  • Wasn't clear form your sample (a) whether two columns could be non-0 or (b) what you'd want in the result if so. Will update to be more generic... – Mark Adelsberger Oct 21 '16 at 20:35
  • I update the question. you can understand the issue. Thank you Mark Adelsberger – Joker Oct 21 '16 at 20:47
  • I agree with you. but it's for ssrs. the process only can be done in SQL. and i cant change the DB. :( – Joker Oct 21 '16 at 21:01
  • Ah... Well, if it's a SQL Server environment, have you looked at the UNPIVOT operator? It could be considerable help; only trick would be to create the "19" column before unpivot, but I think a view could do that. – Mark Adelsberger Oct 21 '16 at 21:05
1

Using a UNION to collate multiple entries

SELECT tch_function,tch_part,9 AS tch_col FROM TCH WHERE tch_col_09 > 0
UNION
SELECT tch_function,tch_part,10 AS tch_col FROM TCH WHERE tch_col_10 > 0
UNION
SELECT tch_function,tch_part,11 AS tch_col FROM TCH WHERE tch_col_11 > 0
UNION
SELECT tch_function,tch_part,12 AS tch_col FROM TCH WHERE tch_col_12 > 0
UNION
SELECT tch_function,tch_part,13 AS tch_col FROM TCH WHERE tch_col_13 > 0
UNION
SELECT tch_function,tch_part,14 AS tch_col FROM TCH WHERE tch_col_14 > 0
UNION
SELECT tch_function,tch_part,15 AS tch_col FROM TCH WHERE tch_col_15 > 0
UNION
SELECT tch_function,tch_part,16 AS tch_col FROM TCH WHERE tch_col_16 > 0
UNION
SELECT tch_function,tch_part,17 AS tch_col FROM TCH WHERE tch_col_17 > 0
UNION
SELECT tch_function,tch_part,18 AS tch_col FROM TCH WHERE tch_col_18 > 0
UNION
SELECT tch_function,tch_part,19 AS tch_col FROM TCH 
WHERE tch_col_09 = 0 AND  tch_col_10 = 0 AND tch_col_11 = 0 
  AND tch_col_12 = 0 AND tch_col_13 = 0 AND tch_col_14 = 0
  AND tch_col_15 = 0 AND tch_col_16 = 0 AND tch_col_17 = 0
  AND tch_col_18 = 0
ORDER BY 1,2  
Stavr00
  • 3,219
  • 1
  • 16
  • 28