Create a constant in Postgresql - postgresql

Suppose that I have this query:
select *
from myTable
where myTable.myCol in (1,2,3)
I would like to do that:
with allowed_values as (1,2,3)
select *
from myTable
where myTable.myCol in allowed_values
It gives me a Syntax Error in the first row, can you help me fixing it?

The closest I can think to your syntax:
WITH allowed_values (id) AS
( VALUES
(1), (2), (3)
)
SELECT *
FROM myTable
WHERE id IN
(TABLE allowed_values) ;
Tested in SQL-Fiddle

Close to what you probably had in mind:
WITH allowed_values AS (SELECT '{1,2,3}'::int[] AS arr)
SELECT *
FROM my_table
,allowed_values -- cross join with a single row
WHERE my_col = ANY (arr);
Better:
WITH allowed_values (my_col) AS (VALUES (1), (2), (3))
SELECT *
FROM allowed_values
JOIN my_table USING (my_col)
But really, you can just simplify:
SELECT *
FROM (VALUES (1), (2), (3)) AS allowed_values (my_col)
JOIN my_table USING (my_col);

Try
with allowed_values as (select 1 as tst union all select 2 union all select 3)
select * from myTable a
inner join c1 b ON (b.tst = a.myCol)

The simplest way forward is to correct your common table expression, then use it in a subselect.
with allowed_values as (
select 1 id
union all
select 2
union all
select 3
)
select * from myTable
where myTable.id in (select id from allowed_values)

Related

insert into temp table without creating it from union results

I have the below query that get results from more than one select.
Now I want these to be in a temp table.
Is there any way to insert these into a temp table without creating the table?
I know how to do that for select
Select * into #s --like that
However how to do that one more than one select?
SELECT Ori.[GeoBoundaryAssId], Ori.[FromGeoBoundaryId], Ori.Sort
From [GeoBoundaryAss] As Ori where Ori.[FromGeoBoundaryId] = (select distinct [FromGeoBoundaryId] from inserted )
Union
SELECT I.[GeoBoundaryAssId], I.[FromGeoBoundaryId], I.Sort
From [inserted] I ;
Add INTO after the first SELECT.
SELECT Ori.[GeoBoundaryAssId], Ori.[FromGeoBoundaryId], Ori.Sort
INTO #s
From [GeoBoundaryAss] As Ori where Ori.[FromGeoBoundaryId] = (select distinct [FromGeoBoundaryId] from inserted )
Union
SELECT I.[GeoBoundaryAssId], I.[FromGeoBoundaryId], I.Sort
From [inserted] I ;
Try this,
INSERT INTO #s ([GeoBoundaryAssId], [FromGeoBoundaryId], Sort)
(
SELECT Ori.[GeoBoundaryAssId], Ori.[FromGeoBoundaryId], Ori.Sort
FROM [GeoBoundaryAss] AS Ori WHERE Ori.[FromGeoBoundaryId] in (SELECT DISTINCT [FromGeoBoundaryId] FROM inserted )
UNION
SELECT I.[GeoBoundaryAssId], I.[FromGeoBoundaryId], I.Sort
FROM [inserted] I
)

postgresql where clause behavior

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.

How to make derived column in Oracle and then use it?

How I can make/declare/define a derived column in select query and then use it in where clause?
To define a column in an SQL query, you can use pretty much any SQL operation that returns a single value (including select statements). Here are some examples:
select 'Y' from dual;
select (5 * 3) cal_col from dual;
select (select min(col1) from table 2) calc_col from dual;
select nvl(col1, 'N') has_value from mytable;
From my experience, if you want to use a derived column in a select query, then you must define the column as part of an inner select. Here is an example:
select *
from (
select (col1 * col2) calc_col
from mytable
) data
where data.calc_col > 30
Another alternative is use the calculation within the where clause itself:
select (col1 * col2) calc_col
from mytable t
where (col1 * col2) > 30
If you are performing a count(*) operation, then you can also leverage the HAVING clause:
select field1, count(*)
from mytable
having count(*) > 3

Select distinct from another select results

I want to select distinct results from another select statement results
e.g;
select distinct from(select * from table)
following is result of inner select
testing department 9998901036 GOLD
testing department 9998901036 GOLD
I want to get distinct from above select result.
From your example, you could just do
select distinct * from table
But say you had some scenario where you wanted to distinct on some other results set, you could do
select distinct column1, column2 from (select * from table) T
Note that you have to alias your inner select
select distinct *
from
(select * from table) t
Works - You just need to give your sub select a table alias.
You can also use a CTE.
;WITH t AS
(
SELECT *
FROM table
)
SELECT DISTINCT *
FROM t

Aggregate GREATEST in T-SQL

My SQL is rusty -- I have a simple requirement to calculate the sum of the greater of two column values:
CREATE TABLE [dbo].[Test]
(
column1 int NOT NULL,
column2 int NOT NULL
);
insert into Test (column1, column2) values (2,3)
insert into Test (column1, column2) values (6,3)
insert into Test (column1, column2) values (4,6)
insert into Test (column1, column2) values (9,1)
insert into Test (column1, column2) values (5,8)
In the absence of the GREATEST function in SQL Server, I can get the larger of the two columns with this:
select column1, column2, (select max(c)
from (select column1 as c
union all
select column2) as cs) Greatest
from test
And I was hoping that I could simply sum them thus:
select sum((select max(c)
from (select column1 as c
union all
select column2) as cs))
from test
But no dice:
Msg 130, Level 15, State 1, Line 7
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
Is this possible in T-SQL without resorting to a procedure/temp table?
UPDATE: Eran, thanks - I used this approach. My final expression is a little more complicated, however, and I'm wondering about performance in this case:
SUM(CASE WHEN ABS(column1 * column2) > ABS(column3 * column4)
THEN column5 * ABS(column1 * column2) * column6
ELSE column5 * ABS(column3 * column4) * column6 END)
Try this:
SELECT SUM(CASE WHEN column1 > column2
THEN column1
ELSE column2 END)
FROM test
Try this... Its not the best performing option, but should work.
SELECT
'LargerValue' = CASE
WHEN SUM(c1) >= SUM(c2) THEN SUM(c1)
ELSE SUM(c2)
END
FROM Test
SELECT
SUM(MaximumValue)
FROM (
SELECT
CASE WHEN column1 > column2
THEN
column1
ELSE
column2
END AS MaximumValue
FROM
Test
) A
FYI, the more complicated case should be fine, so long as all of those columns are part of the same table. It's still looking up the same number of rows, so performance should be very similar to the simpler case (as SQL Server performance is usually IO bound).
How to find max from single row data
-- eg (empid , data1,data2,data3 )
select emplid , max(tmp.a)
from
(select emplid,date1 from table
union
select emplid,date2 from table
union
select emplid,date3 from table
) tmp , table
where tmp.emplid = table.emplid
select sum(id) from (
select (select max(c)
from (select column1 as c
union all
select column2) as cs) id
from test
)
The best answer to this is simply put :
;With Greatest_CTE As
(
Select ( Select Max(ValueField) From ( Values (column1), (column2) ) ValueTable(ValueField) ) Greatest
From Test
)
Select Sum(Greatest)
From Greatest_CTE
It scales a lot better than the other answers with more than two value columns.