Using distinct in case condition sql - sql

Is there a way to use distinct in the case statement in sql ?
For example -
CASE WHEN col1 = 'XYZ' and DISTINCT(col1,col2)
THEN 'Do_This'
ELSE 'Do_That'
END
Unfortunately the usage of DISTINCT inside the case statement as above throws an error.
I'm using postgres/redshift sql.

First of all your objective is not clear but from your query my assumption is as you want to DO_This or Do_That depending on col1 values as 'XYZ' with group by col 1, col2.
SELECT
CASE WHEN COL1 = 'XYZ'
THEN 'DO_THIS'
ELSE 'DO_THAT'
END
FROM
(
SELECT
COL1, COL2
FROM YOUR_TABLE
GROUP BY COL1, COL2
)

Related

How to count a number of unique rows considering that A, B row = B, A row

I am a new in SQL therefore sorry in advance for possible mistakes, incorrect questions.
I am trying to solve the following task:
There is a table with two columns.
My task is to COUNT the number of unique rows, considering that the rows which have the same information (regardless of the order) are counted as 1.
EG. row [1] a b and row [2] b a should be counted as 1
So the result of the query should be 3
You can use aggregation:
select (case when col1 < col2 then col1 else col2 end) as least,
(case when col1 < col2 then col2 else col3 end) as greatest,
count(*)
from t
group by (case when col1 < col2 then col1 else col2 end),
(case when col1 < col2 then col2 else col3 end);
Many databases support the least() and greatest() functions which simplify this logic a bit.
Try the following:
select *, count(*)
from
(
select
case when Column2<Column1 then Column2 else Column1 end as Column1,
case when Column1>Column2 then Column1 else Column2 end as Column2
from tab
) as t
group by Column1,Column2
Example here.
Not the most efficient way of doing it, but if you don't need to group by, here is another method:
select
count(distinct case when col2<col1 then concat(col2,col1) else concat(col1,col2) end)
from your_table;

SQL return column based on other column

i have
SELECT col, col1 from table
CASE
WHEN other_col = 'Canada' THEN 1
ELSE 2
END AS col2
it works fine, but i want to calculate
col3 based on value from col2
it should be simple col3 = value from col2 / 2
and return it in the same select
How to achieve it?
You can't use the column col2 in an expression like col2 / 2 inside the same select statement.
You can repeat the same CASE statement like this:
SELECT
col,
col1,
CASE WHEN other_col = 'Canada' THEN 1 ELSE 2 END AS col2
CASE WHEN other_col = 'Canada' THEN 0.5 ELSE 1 END AS col3
FROM table
or by nesting the SELECT statement inside another:
SELECT
t.*,
t.col2 / 2 AS col3
FROM (
SELECT
col,
col1,
CASE WHEN other_col = 'Canada' THEN 1 ELSE 2 END AS col2
FROM table
) AS t
The reason you can't use the alias is because of the 'all at once' expression evaluation.
Expressions are not evaluated in order, but 'all at once' which also allows you to do things like
UPDATE Table SET Col1 = Col2, Col2 = Col1...
Which would not be possible if the expressions were processed in order.
IMHO it's easier and clearer to use CTE instead of repeating the CASE.
;WITH CTE AS
(
SELECT col, col1, CASE
WHEN other_col = 'Canada'
THEN 1
ELSE 2
END AS col2
FROM table
)
SELECT *, <Whatever Function On (Col2).
FROM CTE;
You can use a lateral join in Postgres:
SELECT t.col, t.col1, v.col2
FROM table t CROSS JOIN LATERAL
(VALUES (CASE WHEN other_col = 'Canada' THEN 1 ELSE 2 END)
) v(col2);
You can then use v.col2 to your heart's delight in any other expression you want to.

Oracle SQL Unions error "query block has incorrect number of results columns"

I'm trying to write a query that pulls data from a lot of tables, and has about 20 unions. It's pulling the same information repeatedly, but with more layers each time, to show a sort of tree.
I want to compare the final two columns. I'm using a case to do this, and if I add a case to this query then I get the error "query block has incorrect number of results columns". This seems to be because the final select in the union has an extra column (the compare case).
Is there any way to work around this? I don't want to add the case to each select, as this would add about 15 more columns that I don't want.
Use a sub-query:
SELECT col1,
col2,
CASE
WHEN col1 = 'somevalue'
THEN 'someresult'
ELSE 'otherresult'
END AS col3
FROM (
SELECT col1, col2 FROM table1 UNION ALL
SELECT col1, col2 FROM table2 UNION ALL
SELECT col1, col2 FROM table3
-- ...
);
Or use a sub-query factoring clause:
WITH data ( col1, col2 ) AS (
SELECT col1, col2 FROM table1 UNION ALL
SELECT col1, col2 FROM table2 UNION ALL
SELECT col1, col2 FROM table3
-- ...
)
SELECT col1,
col2,
CASE
WHEN col1 = 'somevalue'
THEN 'someresult'
ELSE 'otherresult'
END AS col3
FROM data;

Sybase: How can I use "Select into" statement if I am not sure if the table always have rows or not

I need to use the select into statement:
Query
Select * into table2 from table1
This statement works perfectly if I have rows in the table1. However, in my case sometimes I might have rows in table1 while other times I don't.
Any ideas of how to deal with such a case please? My DB is Sybase
Why not check to see if there is any data there to start with like so:
if exists (select * from table1)
Select * into table2 from table1
You could use IF statement and COUNT function to check if rows exist in table.
IF ((SELECT COUNT(*) FROM Table1) >= 1)
BEGIN
SELECT * INTO table2 FROM table1
END
Or you can use EXISTS condition.
IF EXISTS (SELECT * FROM Table1)
BEGIN
SELECT * INTO table2 FROM table1
END
AS you said that you can't use IF statement you could try something like this:
INSERT * INTO Table2 (col1, col2, col3)
SELECT (CASE WHEN col1 IS NOT NULL THEN col1 ELSE NULL END) AS col1,
(CASE WHEN col2 IS NOT NULL THEN col1 ELSE NULL END) AS col2,
(CASE WHEN col2 IS NOT NULL THEN col1 ELSE NULL END) AS col3
FROM Table1
You got to use dynamic sql:
if object_id("table1") is not null
EXEC ("Select * into table2 from table1")
this code will pass compilation, none of the ones above will.
2 others condition to succeed :
1) the option select into/bulkcopy/pllsort must be on
2) I think that this capability has been added since sybase 15.7 sp101
==> issue select ##version to check your server version

Multiple Subqueries and Conditions

If I have a subquery which does the following;
Select
Min(S_Date)
, Col1
, Col2
From
(
Select Dateadd(whatever) as S_Date, Userid
from tbl1 as t
where S_Date >'today'
)
How can I add another clause so that value from Col1 is only selected if another condition is met, i.e col3 = 'doit'. I guess I am trouble understanding how to use two where clauses in different places in a subquery.
You need to use a CASE statement:
SELECT
s_date
,CASE Col3 WHEN 'doit' THEN Col1 ELSE Col2 END AS selection
FROM (
SELECT
Sdate
, Col1
, Col2
, Col3
FROM foo
WHERE s_Date > GETDATE()
) AS sub
To use aggregate functions like MIN() you need to group by the columns you're not aggregating...
Select
Min(S_Date)
, Col1
, Col2
From
(
Select Dateadd(whatever) as S_Date, Userid
from tbl1 as t
where S_Date >'today'
)
GROUP BY
Col1,
Col2
If you then want the non-aggregated columns to be conditional, you again group by those conditional values...
Select
Min(S_Date)
, CASE WHEN col3 = 'doit' THEN Col1 ELSE Col2 END AS conditional_field
From
(
Select Dateadd(whatever) as S_Date, Userid
from tbl1 as t
where S_Date >'today'
)
GROUP BY
CASE WHEN col3 = 'doit' THEN Col1 ELSE Col2 END
I'm not 100% sure what you actually want to achieve though. Do you have a sample set of data, with the results you want, and an explanation of how the results relate to the source?