开发者

Finding the first row from a hardcoded list of column values (Pivot problem?)

I am trying to extract a column value from the "first" row that satisfies some criteria, where "first" is defined by a hard-coded list of column values. Unfortunately I'm a SQL amateur. I'm using DB2.

I can do it inefficiently like this:

SELECT COALESCE(
  (SELECT COL FROM SOMETABLE WHERE X = "txt1" AND Y = "txt2" AND COL = 'A'), 
  (SELECT COL FROM SOMETABLE WHERE X = "txt1" AND Y = "txt2" AND COL = 'B'), 
  (SELECT COL FROM SOMETABLE WHERE X = "txt1" AND Y = "txt2" AND COL = 'C'), 
  (SELECT COL FROM SOMETABLE WHERE X = "txt1" AND Y = "txt2" AND COL = 'D') 
)

The problem here is that SOMETABLE开发者_StackOverflow中文版 is very big. So instead I would like to do something like:

SELECT COALESCE(
  (SELECT COL FROM T WHERE COL = 'A'), 
  (SELECT COL FROM T WHERE COL = 'B'), 
  (SELECT COL FROM T WHERE COL = 'C'), 
  (SELECT COL FROM T WHERE COL = 'D') 
)
FROM 
  (SELECT COL FROM SOMETABLE WHERE X = "txt1" AND Y = "txt2") AS T

This is invalid, since I cannot reference the T table.

Assume that T above contains the following rows:

'E'
'B'
'D'

Then I would like to pick 'B', because it is the first value specified in the COALESCE statement.

I realise I can get somewhat nearer what I want by doing something like:

SELECT 
  (CASE COL WHEN 'A' THEN COL ELSE NULL END), 
  (CASE COL WHEN 'B' THEN COL ELSE NULL END), 
  (CASE COL WHEN 'C' THEN COL ELSE NULL END),
  (CASE COL WHEN 'D' THEN COL ELSE NULL END)
FROM 
  (SELECT COL FROM SOMETABLE WHERE X = "txt1" AND Y = "txt2") AS T

This yields the result:

-   -   -   -
-   -   -   D
-   B   -   -

Now I would like to aggregate or "flatten" this into a single row like so:

-   B   -   D

And then I would simply coalesce on the columns.

Any suggestions would be greatly appreciated!


Providing your hard coded values sort in order appropriate to your question, then :

SELECT COL   
FROM SOMETABLE   
WHERE X = "txt1"   
AND Y = "txt2"   
ORDER BY col   
fetch first 1 rows only


I think I found a solution.

SELECT COALESCE(
  MAX(CASE COL WHEN 'A' THEN COL ELSE NULL END), 
  MAX(CASE COL WHEN 'B' THEN COL ELSE NULL END), 
  MAX(CASE COL WHEN 'C' THEN COL ELSE NULL END),
  MAX(CASE COL WHEN 'D' THEN COL ELSE NULL END))
FROM 
  (SELECT COL FROM SOMETABLE WHERE X = "txt1" AND Y = "txt2") AS T

Please let me know if and how this is stupid or wrong.


If I understand your question correctly, you can convert

SELECT COALESCE(  
    (SELECT COL FROM T WHERE COL = 'A'),   
    (SELECT COL FROM T WHERE COL = 'B'),   
    (SELECT COL FROM T WHERE COL = 'C'),   
    (SELECT COL FROM T WHERE COL = 'D') )
FROM   (SELECT COL FROM SOMETABLE WHERE X = "txt1" AND Y = "txt2") AS T

to CTE as under:

WITH T AS (
    SELECT COL FROM SOMETABLE WHERE X = "txt1" AND Y = "txt2"
)
SELECT COALESCE(  
    (SELECT COL FROM T WHERE COL = 'A'),   
    (SELECT COL FROM T WHERE COL = 'B'),   
    (SELECT COL FROM T WHERE COL = 'C'),   
    (SELECT COL FROM T WHERE COL = 'D') )
FROM T;

or something like this. I can't test it as I don't have a DB2 database.


You were pretty close with this…

SELECT COALESCE(
  MAX(CASE COL WHEN 'A' THEN COL ELSE NULL END), 
  MAX(CASE COL WHEN 'B' THEN COL ELSE NULL END), 
  MAX(CASE COL WHEN 'C' THEN COL ELSE NULL END),
  MAX(CASE COL WHEN 'D' THEN COL ELSE NULL END))
FROM 
  (SELECT COL FROM SOMETABLE WHERE X = "txt1" AND Y = "txt2") AS T

You don't need the coalesce (can't use this around multiple columns) and you don't need the subquery (the where clause is always evaluated first)

SELECT MAX(CASE WHEN COL = 'A' THEN COL ELSE NULL END) AS A, 
       MAX(CASE WHEN COL = 'B' THEN COL ELSE NULL END) AS B, 
       MAX(CASE WHEN COL = 'C' THEN COL ELSE NULL END) AS C,
       MAX(CASE WHEN COL = 'D' THEN COL ELSE NULL END) AS D
  FROM SOMETABLE 
 WHERE X = "txt1" 
   AND Y = "txt2"

Some databases support the ANSI SQL standard PIVOT function which does a similar (but not identical) thing. It doesn't sound like DB2/400 has many advanced features though.

Joe

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜