Is it possible to return multiple column on single CASE evaluation in DB2?
below query return single column.
select (case when 1=1 then 0 else 1 end) as col from table;
I need multiple column like
select (case when 1=1 then 0 as col, 1 as col1 else 2 as col1 , 3 as col2 end) from table;
select (case when 1=1 then 0,1 else 2, 3 end)col , col1 from table;
Is coalesce function is use full for above conditions? thanks.
It’s not possible with a single CASE statement in Db2.
But you may use something like below.
select
coalesce(t1.c1, t2.c1, t3.c1) c1
, coalesce(t1.c2, t2.c2, t3.c2) c2
from
(
select tabschema, tabname, rownumber() over (partition by tabschema) rn_
from syscat.tables
) b
left join table(values ('_SYSIBM_', b.tabname)) t1 (c1, c2) on b.tabschema='SYSIBM'
left join table(values ('_SYSCAT_', b.tabname)) t2 (c1, c2) on b.tabschema='SYSCAT'
cross join table(values (b.tabschema, b.tabname)) t3 (c1, c2)
where b.rn_=1;
The sub-select on syscat.tables is constructed to return only one table from each schema just to show the idea (your base table must be there instead of it). "Case condition" here is what you see in the on clause of each join. "Returned values" of this "Case expression" are inside the values clauses.
A CASE statement can be re-written as a UNION. Logically they are the same thing.
So, you could do this
select 0 as col, 1 as col1 from table where 1=1
UNION ALL
select 2 as col, 3 as col1 from table where NOT 1=1 OR 1=1 IS NULL
Related
I have a query like this, and appearantly Impala doesn't support subqueries in SELECT statement. How can I neatly rewrite it in Impala?
SELECT
col1,
col2,
...
CASE
WHEN (SELECT 1
FROM
table1 x,
table2 y
WHERE
x.id = y.id
LIMIT 1) = 1
THEN
'A'
ELSE
'B'
END
coln
FROM
...
Your query has the following error(s):
AnalysisException: Subqueries are not supported in the select list.
You could try
SELECT col1, col2, ... 'A' coln
FROM ...
WHERE EXISTS (SELECT 1 FROM table1 x, table2 y WHERE x.id = y.id LIMIT 1)
UNION ALL
SELECT col1, col2, ... 'B' coln
FROM ...
WHERE NOT EXISTS (SELECT 1 FROM table1 x, table2 y WHERE x.id = y.id LIMIT 1)
No guarantees, haven't tried it myself.
In general, a cleaner solution is placing the subqueries into the FROM clause, thereby linking the subqueries to the main table through inner or left joins. I usually do this when dealing with complex types in Impala.
However, in your specific example you are trying to do a left join, defining a field for each row which indicates whether the join was successful ('A') or not ('B'). In this case you could do the following:
SELECT
x.id, x.col2, x.col3, ...
CASE
WHEN y.id IS NOT NULL THEN 'A'
ELSE 'B'
END
coln
FROM table1 x LEFT JOIN
table2 y USING (id)
...
Hello with this query I'm getting one result with four rows, how can I change it in order to get four named columns with their own result every one?
SELECT COUNT(*) FROM vehicles WHERE cus=1
UNION ALL
SELECT COUNT(*) FROM user WHERE cus=1
UNION ALL
SELECT COUNT(*) FROM vehicle_events WHERE cus=1
UNION ALL
SELECT COUNT(*) FROM vehicle_alerts WHERE cus=1
Thanks in advance.
SELECT a.ct veh_count, b.ct user_count, c.ct event_count, d.ct alert_count
FROM
( SELECT COUNT(*) ct FROM vehicles WHERE cus=1 ) a,
( SELECT COUNT(*) ct FROM user WHERE cus=1 ) b,
( SELECT COUNT(*) ct FROM vehicle_events WHERE cus=1 ) c,
( SELECT COUNT(*) ct FROM vehicle_alerts WHERE cus=1 ) d;
UNION only adds rows; it has no effect on the columns.
Columns, which define the "shape" of the row tuples, must appear as selected columns1.
For example:
SELECT
(SELECT COUNT(*) FROM vehicles WHERE cus=1) as veh_count
,(SELECT COUNT(*) FROM users WHERE cus=1) as user_count
..
1 There are other constructs that can allow this, see crosstab for example - but the columns are fixed by the query command. It takes dynamic SQL to get a variable number of columns.
Problem:
I need to remove duplicate pairs from the result of a query
(same problem as described here)
So if the result has (A,B), (B,A), (C,A)
I am only interested in (A,B) and (C,A)
The Complication:
Unlike in the linked question, the data is not available in a table to perform an self join and retrieve easily. It is more in the following state
(SELECT C1, C2 from a mind boggling number of joins and unions)
So I can make it a temp table as follows
SELECT T.C1, T.C2
((SELECT C1, C2 from a mind boggling number of joins and unions)) T1
I would like to perform an inner join to remove duplicate pairs as mentioned above
So is there a way to do that in such a scenario
Below query is syntactically wrong, but hopefully it conveys the idea
SELECT A.C1, A.C2
((SELECT C1, C2 from a mind boggling number of joins and unions)) T1 A
INNER JOIN T1 B
ON A.C1 = B.C1 AND
A.C2 < B.C2
I am running SQL Server 2012
here is one way to achieve what you want with CTEs
you can as well use temporary table to store result and use cte1 alone.
with cte
as
(
select col1, col2 from --- your query here.
)
, cte1
as
(
select col1, col2, row_number() over
( partition by (case when col1 >= col2 then col1
else col2
end) ,
(case when col1 <= col2 then col1
else col2
end) order by (select null)
) as rn
from cte
)
select * from cte1 where rn =1
I have a field called "Users", and I want to run SUM() on that field that returns the sum of all DISTINCT records. I thought that this would work:
SELECT SUM(DISTINCT table_name.users)
FROM table_name
But it's not selecting DISTINCT records, it's just running as if I had run SUM(table_name.users).
What would I have to do to add only the distinct records from this field?
Use count()
SELECT count(DISTINCT table_name.users)
FROM table_name
SQLFiddle demo
This code seems to indicate sum(distinct ) and sum() return different values.
with t as (
select 1 as a
union all
select '1'
union all
select '2'
union all
select '4'
)
select sum(distinct a) as DistinctSum, sum(a) as allSum, count(distinct a) as distinctCount, count(a) as allCount from t
Do you actually have non-distinct values?
select count(1), users
from table_name
group by users
having count(1) > 1
If not, the sums will be identical.
You can see for yourself that distinct works with the following example. Here I create a subquery with duplicate values, then I do a sum distinct on those values.
select DistinctSum=sum(distinct x), RegularSum=Sum(x)
from
(
select x=1
union All
select 1
union All
select 2
union All
select 2
) x
You can see that the distinct sum column returns 3 and the regular sum returns 6 in this example.
You can use a sub-query:
select sum(users)
from (select distinct users from table_name);
SUM(DISTINCTROW table_name.something)
It worked for me (innodb).
Description - "DISTINCTROW omits data based on entire duplicate records, not just duplicate fields." http://office.microsoft.com/en-001/access-help/all-distinct-distinctrow-top-predicates-HA001231351.aspx
;WITH cte
as
(
SELECT table_name.users , rn = ROW_NUMBER() OVER (PARTITION BY users ORDER BY users)
FROM table_name
)
SELECT SUM(users)
FROM cte
WHERE rn = 1
SQL Fiddle
Try here yourself
TEST
DECLARE #table_name Table (Users INT );
INSERT INTO #table_name Values (1),(1),(1),(3),(3),(5),(5);
;WITH cte
as
(
SELECT users , rn = ROW_NUMBER() OVER (PARTITION BY users ORDER BY users)
FROM #table_name
)
SELECT SUM(users) DisSum
FROM cte
WHERE rn = 1
Result
DisSum
9
If circumstances make it difficult to weave a "distinct" into the sum clause, it will usually be possible to add an extra "where" clause to the entire query - something like:
select sum(t.ColToSum)
from SomeTable t
where (select count(*) from SomeTable t1 where t1.ColToSum = t.ColToSum and t1.ID < t.ID) = 0
May be a duplicate to
Trying to sum distinct values SQL
As per Declan_K's answer:
Get the distinct list first...
SELECT SUM(SQ.COST)
FROM
(SELECT DISTINCT [Tracking #] as TRACK,[Ship Cost] as COST FROM YourTable) SQ
I made two queries that I thought should have the same result:
SELECT COUNT(*) FROM (
SELECT DISTINCT ON (id1) id1, value
FROM (
SELECT table1.id1, table2.value
FROM table1
JOIN table2 ON table1.id1=table2.id
WHERE table2.value = '1')
AS result1 ORDER BY id1)
AS result2;
SELECT COUNT(*) FROM (
SELECT DISTINCT ON (id1) id1, value
FROM (
SELECT table1.id1, table2.value
FROM table1
JOIN table2 ON table1.id1=table2.id
)
AS result1 ORDER BY id1)
AS result2
WHERE value = '1';
The only difference being that one had the WHERE clause inside SELECT DISTINCT ON, and the other outside that, but inside SELECT COUNT. But the results were not the same. I don't understand why the position of the WHERE clause should make a difference in this case. Can anyone explain? Or is there a better way to phrase this question?
here's a good way to look at this:
SELECT DISTINCT ON (id) id, value
FROM (select 1 as id, 1 as value
union
select 1 as id, 2 as value) a;
SELECT DISTINCT ON (id) id, value
FROM (select 1 as id, 1 as value
union
select 1 as id, 2 as value) a
WHERE value = 2;
The problem has to do with the unique conditions and what is visible where. It is behavior by design.