Distinct values in cte table - sql

I'm doing a query in SQL like this:
with cte as
(
select
t.ktokk, t.txt30,
case
when t.spras = 'P' then '1'
when t.spras = 'E' then '2'
else '3'
end as ord_ktokk
from
t077y t
order by
ord_ktokk
)
select *
from cte
and the result is that:
[Image]
Now I want to select only the distinct values in ktokk column. How can i do that?
thanks for the help

Related

How can I assign a function result to a name in the WITH clause of a SELECT?

How can I assign a function result to a name in the WITH clause?
Tried:
with
has_perm as ( has_perm(:user) )
select * from my_table where has_perm = 'Y'
Is this what you want?
with has_perm as (
select has_perm(:user) as has_perm
from dual
)
select *
from my_table
where 'Y' = (select has_perm from has_perm);
Why not just write this without a CTE?
select *
from my_table
where has_perm(:user) = 'Y';

How to define unique value in union if two rows are not same data

I'm creating a simple SQL query with union, the result is returned correctly, but how to set a default value in a dummy column if the union result has two rows for one value?
If the result returned two values for one employee, then the dummy column is 'N' for the first value and 'Y' for the second value.
And if the result returned only one value for the employee, then the dummy column is 'Y'
How to achieve that?
This is the query that I'm using
select
dbo.employee,
dbo.starting_date
from
table_1
union
select
dbo.employee,
dbo.hiring_date
from
table_2
With a CTE:
with cte as (
select dbo.employee, dbo.starting_date date from table_1
union all
select dbo.employee, dbo.hiring_date date from table_2
)
select
t.*,
case when exists (
select 1 from cte
where employee = t.employee and date > t.date
) then 'N' else 'Y' end dummycolumn
from cte t
You can use window functions for this:
select t.employee, t.date,
(case when 1 = row_number() over (partition by t.employee order by t.date)
then 'Y' else 'N'
end) as dummy
from ((select t1.employee, t1.starting_date as date
from table_1 t1
) union all
(select t2.employee, t2.starting_date as date
from table_2 t2
)
) t

How to use Dynamic Lag function to avoid joining a table to itself to retrieve date value

I'm currently writing code in SQL to add the column in red to the following table:
The logic is the following:
For every row:
if flag for this row =1 then use date of this row
if flag for this row =0 then find the latest row (based on date) on which flag was = 1 for the same party and return the date of that row. If no such row exists, return null
I've found a way to do this by joining the table to itself but I would like to avoid doing that as the size of the table is pretty massive.
What I have
select b.*, a.date,
from table a left join table b on a.party=b.party
where a.flag =1
Someone told me I could use the lag function, the partition over function and a case when to return the value I'm after but I haven't been able to figure it out.
Can someone help? Thank you so much!
try this
DECLARE #tab1 TABLE(PARTY CHAR(1),DATE DATE,Flag bit)
INSERT INTO #tab1
SELECT 'A','7-24-2018',1 Union ALL
SELECT 'A','7-28-2018',0 Union ALL
SELECT 'A','7-29-2018',0 Union ALL
SELECT 'A','7-29-2018',0 Union ALL
SELECT 'B','7-13-2018',1 Union ALL
SELECT 'B','7-17-2018',0 Union ALL
SELECT 'B','7-18-2018',0 Union ALL
SELECT 'C','7-8-2018',1 Union ALL
SELECT 'C','7-13-2018',0 Union ALL
SELECT 'C','7-19-2018',0 Union ALL
SELECT 'C','7-19-2018',0 Union ALL
SELECT 'C','7-20-2018',0
select t.*,
max(case when flag = 1 then date end) over (partition by PARTY order by date) as [Last Flag On Date]
from #tab1 t
try this :->
select b.*, a.date, from table a left join table b on a.party=b.party where a.flag = CASE WHEN a.flag = 1 THEN a.date WHEN a.flag = 0 THEN ( SELECT date FROM ( SELECT TOP 1 row_number() OVER ( ORDER BY a.date DESC ) rs , a.date FROM a WHERE a.flag = 1 GROUP BY a.date) s ) END
use CROSS APPLY() to obtain the latest row with flag 1
SELECT *
FROM yourtable t
CROSS APPLY
(
SELECT TOP 1 x.Date as [Last flag on date]
FROM yourtable x
WHERE x.Party = t.Party
AND x.Flag = 1
ORDER BY x.Date desc
) d
Yes it can be done by joining table, if written properly.
#Sahi query is also good and simple.
Since you were asking for Dynamic LAG()
This query may or may not be very performant,but it certainly worth learning.
Test this with various sample data and tell me for which scenario it do not work.
So that I correct my script accordingly.
DECLARE #tab1 TABLE(PARTY CHAR(1),DATE DATE,Flag bit)
INSERT INTO #tab1
SELECT 'A','7-24-2018',1 Union ALL
SELECT 'A','7-28-2018',0 Union ALL
SELECT 'A','7-29-2018',0 Union ALL
SELECT 'A','7-29-2018',0 Union ALL
SELECT 'B','7-13-2018',1 Union ALL
SELECT 'B','7-17-2018',0 Union ALL
SELECT 'B','7-18-2018',0 Union ALL
SELECT 'C','7-8-2018',1 Union ALL
SELECT 'C','7-13-2018',0 Union ALL
SELECT 'C','7-19-2018',0 Union ALL
SELECT 'C','7-19-2018',0 Union ALL
SELECT 'C','7-20-2018',0;
WITH cte
AS (SELECT *,
Row_number()
OVER (
partition BY party
ORDER BY flag DESC, [date] DESC ) rn
FROM #tab1)
SELECT *,
CASE
WHEN flag = 1 THEN [date]
ELSE Lag([date], (SELECT TOP 1 a.rn - a1.rn
FROM cte a1
WHERE a1.party = a.party))
OVER (
ORDER BY party )
END
FROM cte a

SQL - WHERE on new column

I've a table with 3 columns: Id, Price, Total.
I'm writing this sql statement:
SELECT Id, Price, Total,
CASE WHEN [Total] IS NULL THEN '0'
WHEN [Total] IS NOT NULL '1'
ELSE ''
END AS NewColumnName
FROM Table
If I run this sql, I have no error. But if I add a Where, like this:
WHERE NewColumnName= '1' the server return an error: the name of column NewColumnName is not valid.
Please help me!
Thanks a lot!!
RM
Can you try this way?
select *
from (
SELECT Id, Price, Total,
CASE WHEN [Total] IS NULL THEN '0'
WHEN [Total] IS NOT NULL '1'
ELSE ''
END AS NewColumnName
FROM Table
) x
where
NewColumnName= '1'
Try this,
SELECT Id, Price, Total,
CASE WHEN [Total] IS NULL THEN '0'
WHEN [Total] IS NOT NULL '1'
END AS NewColumnName
FROM Table
WHERE CASE WHEN [Total] IS NULL THEN '0'
WHEN [Total] IS NOT NULL '1'
END = '1'
Generally use a subquery,
SELECT Id, Price, Total, NewColumnName
FROM (
SELECT
Id,
Price,
Total,
CASE
WHEN [Total] IS NULL THEN '0'
ELSE '1'
END [NewColumnName]
FROM
Table) [WithNew]
WHERE
NewColumnName = '1';
or in your case you could do,
SELECT
Id,
Price,
Total,
1 [NewColumnName]
FROM
Table
WHERE
Total IS NOT NULL;
USE [AdventureWorks2012]
WITH cte as (
SELECT [AddressID], [AddressLine1]
, CASE WHEN [City] = 'Bothell' THEN 1 ELSE 0 END AS [NewColumn]
FROM Person.Address )
SELECT * FROM CTE
WHERE [NewColumn] = 1
So yours would be re-written like this:
WITH cte as (
SELECT Id, Price, Total,
CASE WHEN [Total] IS NULL THEN '0'
WHEN [Total] IS NOT NULL '1'
ELSE ''
END AS NewColumnName
FROM Table)
SELECT * FROM CTE where [NewColumnName] = 1
You can't use NewColumnName in the WHERE Clause. You will have to use the CASE statement again in WHERE Clause or do what #Lajos suggested.
You can just write your query like this:
SELECT Id, Price, Total,
FROM Table
WHERE Total IS NOT NULL
That's doing the same thing, except without the case statement.

Sqlite union and sort order

select 'none', '0'
union
select * from category where id='2'
Can I retrieve the output of above sqlite query as 'none' should always be the first item ?, ie I want to block from a combined sort of two resultsets. plz help...
select * from
(
select 'none' as col1, '0' as col2 union select * from category where id='2'
) t
order by case when col1='none' then 0 else 1 end
I'd avoid using SELECT * in a union query
SELECT 'none', '0', 0 AS sort
UNION
SELECT col1, col2, 1 AS sort
FROM category
WHERE id = '2'
ORDER BY sort ASC