Intersecting N width_buckets - sql

I'm trying to take subsets from bucketed columns, and then take the intersection.
This will select other columns from the original table.
I'm also open to filtering in series.
The code below reports col1 doesn't exist - not sure It's the correct approach anyway.
WITH ranges AS (
SELECT
min(col1) AS c1min,
max(col1) AS c1max,
min(col2) AS c2min,
max(col2) AS c2max
FROM csv_test
),
f1 AS (
SELECT width_bucket(col1,c1min,c1max,12) AS b1
FROM csv_test, ranges
ORDER BY b1 ASC
),
f2 AS (
SELECT width_bucket(col2,c2min,c2max,12) AS b2
FROM csv_test, ranges
ORDER BY b2 ASC
)
SELECT b1, b2, c3, c4, c18
FROM csv_test
WHERE
b1 BETWEEN 0 AND 5
AND
b2 BETWEEN 3 AND 7;

You could use LATERAL join:
SELECT t.*, s2.*
FROM csv_test t
,LATERAL (SELECT
min(col1) AS c1min,
max(col1) AS c1max,
min(col2) AS c2min,
max(col2) AS c2max
FROM csv_test) AS s
,LATERAL (SELECT width_bucket(col1,c1min,c1max,12) AS b1,
width_bucket(col2,c2min,c2max,12) AS b2) AS s2
WHERE b1 BETWEEN 0 AND 5
AND b2 BETWEEN 3 AND 7;
DBFiddle Demo

Related

postgresql - count distinct combination of three columns- order doesn't matter

I'm trying to count distinct combinations of three columns, order of the columns doesn't matter
sample :
a a a
a a b
a b a
b b a
b a b
the result I'm getting :
a a a 1
a a b 1
a b a 1
b b a 1
b a b 1
desired result
aaa 1
aab 2
bba 2
You can use an ordered array
select v[1], v[2], v[3], count(*) n
from tbl t
cross join lateral (
select array_agg(col order by col) v
from (
values (c1),(c2),(c3)
) t(col)
) s
group by v[1], v[2], v[3];
db<>fiddle
Maybe you can use checksums for getting the required result eg if it is really just combinations 'a' and 'b' that you are dealing with, you could convert the letters to integers (by calling the ASCII() function) and add these up so that you get a checksum.
TABLE
create table t (c1, c2, c3 ) as
select 'a', 'a', 'a' union all
select 'a', 'a', 'b' union all
select 'a', 'b', 'a' union all
select 'b', 'b', 'a' union all
select 'b', 'a', 'b' ;
Checksums
select c1, c2, c3, ascii( c1 ) + ascii( c2 ) + ascii( c3 ) as checksum
from t ;
-- output
c1 c2 c3 checksum
a a a 291
a a b 292
a b a 292
b b a 293
b a b 293
If this works for you, then you can use window functions eg
select c1, c2, c3, rc_ as rowcount
from (
select c1, c2, c3
, count(*) over ( partition by ascii( c1 ) + ascii( c2 ) + ascii( c3 ) order by 1 ) rc_
, row_number() over ( partition by ascii( c1 ) + ascii( c2 ) + ascii( c3 ) order by 1 ) rn_
from t
) sq
where rc_ = rn_ ;
-- output
c1 c2 c3 rowcount
a a a 1
a b a 2
b a b 2
See dbfiddle.
If you are dealing with strings that cannot easily converted to integers, you could create a mapping between the strings and integers, and implement the map_ as a view (so that it is easy to use in subsequent queries) eg
MAP
-- {1} find all distinct elements
-- {2} map each element to an integer
create view map_
as
select val_, rank() over ( order by val_ ) weight_
from (
select distinct val_
from (
select distinct c1 val_ from t union all
select distinct c2 from t union all
select distinct c3 from t
) all_elements
) unique_elements ;
Once you have this map, you can use its values for creating checksums (maybe also in a view) ...
Checksums
create view t_checksums_
as
select c1, c2, c3, c1weight + c2weight + c3weight as checksum
from (
select
c1, ( select weight_ from map_ where c1 = map_.val_ ) c1weight
, c2, ( select weight_ from map_ where c2 = map_.val_ ) c2weight
, c3, ( select weight_ from map_ where c3 = map_.val_ ) c3weight
from t
) valandweight ;
... and then, you can use the same query as before, for obtaining the final result - see dbfiddle.

Table data show one by one record different two tables?

Table 1
ABC
DEF
GS
PM
BS
PK
Table 2
ABC
DEF
YZ
TT
UG
KK
Need output
ABC
DEF
GS
PM
YZ
TT
BS
PK
UG
KK
So please help me sql query
table1:
Azbuka
Def
A1
D1
A2
D2
A3
D3
A4
D4
table2:
Azbuka
Def
F1
H1
F2
H2
F3
H3
F4
H4
DECLARE #max INT
select #max = count(*) from table1
;WITH CTE AS (
SELECT 1 num
UNION ALL
SELECT num+1
FROM CTE
WHERE num<#max
)
SELECT t1.* FROM CTE CC
inner join
(
Select
ROW_NUMBER() OVER(ORDER BY id ASC) AS RNum,
Azbuka,
Def
from table1
union all
Select
ROW_NUMBER() OVER(ORDER BY id ASC) AS RNum,
Azbuka,
Def
from table2
) t1 on t1.RNum = CC.num
Result:
Azbuka
Def
A1
D1
F1
H1
A2
D2
F2
H2
A3
D3
F3
F3
A4
D4
F4
H4
A more simple example and without recursive:
Select main.Azbuka, main.Def from (
Select
(ROW_NUMBER() OVER(ORDER BY id ASC))*2 AS RNum,
Azbuka,
Def
from TEST_DB.dbo.table1
union all
Select
((ROW_NUMBER() OVER(ORDER BY id ASC))*2 + 1) AS RNum,
Azbuka,
Def
from TEST_DB.dbo.table2
) main
order by main.RNum

oracle transposing rows to columns

my question is about transposing rows into columns.
I have got table T1(c1,c2,c3,c4,c5) columns with datatype varchar2, i want to transpose the rows obtained,
example:
select * from T1
gives
c1 c2 c3 c4 c5
row1 1 2 3 4 5
row2 A B C D E
....
rown U V W X Y
the result expected is
C1 1 A......U
C2 2 B......V
C3 3 C......W
C4 4 D......X
C5 5 E......Y
all rows in different columns(table contains only 10-15 rows)
i have tried the following query, but it isnt giving expected result.
Select RN,value
From (
Select x.*,row_number ()
Over ( Order By c1) rn From T1 x)
Unpivot (value For value_type In (C1,c2,c3,c4,c5)
);
So you only need to pivot data again:
dbfiddle demo
select *
from (
select rn, val, col
from (select t1.*, row_number() over (order by c1) rn from t1)
unpivot (val for col in (c1, c2, c3, c4, c5)))
pivot (max(val) for rn in (1, 2, 3, 4))
order by col
You have to know how many rows are in t1 and list them all in pivot in clause (1, 2, 3, 4) alternatively adding aliases for each column.

count of distinct columns in a record

How to count distinct columns values for a record
C1 C2 C3 C4
1 USER1 USER2 USER3
2 USER1 USER1 USER2
3 USER2 USER3 USER3
4 USER1 USER1 USER1
OUTPUT:
C1 COUNT
1 3
2 2
3 2
4 1
How to calculate distinct number of users in each record. Is there a way other than comparing column values.
Thanks.
One way is with unpivot:
select c1, count(distinct col) as cnt from (
select * from your_table
unpivot( col for lst in(C2, C3, C4) )
) tt
group by c1
For only three comparison columns this is the simplest thing which would work:
with cte as (
select c1, c2 from your_table
union
select c1, c3 from your_table
union
select c1, c4 from your_table
)
select c1, count(c2) as cnt
from cte
group by c1
/
The union operator produces a distinct set which feeds into the aggregated count.
with cte as (
select c1, c2 from your_table
union all
select c1, c3 from your_table
union all
select c1, c4 from your_table
)
select c1, count(c2) as cnt,count(distinct c2) as distinct_cnt
from cte
group by c1
/

Select only rows that have unique fields

What is an SQL command that checks for rows that have rows with no duplicate fields in them.
ex:
A A A B B B should not be in the resulting table.
Only rows such as A B C D E F
i.e. given data like:
A A A B B B
A B C D E F
A A B G H Q
Should return A B C D E F
There is no simple command to do this.
is seems an unusual requirement and possibly an indication that the table is not in first normal form if all columns are interchangeable.
The following works in Microsoft SQL Server
;With YourData AS
(
select 'A' as C1, 'A' as C2, 'A' as C3, 'B' as C4, 'B' as C5, 'B' as C6 UNION ALL
select 'A' as C1, 'B' as C2, 'C' as C3, 'D' as C4, 'E' as C5, 'F' as C6
)
SELECT *
FROM YourData
WHERE 1 =
( SELECT TOP 1 COUNT(*) AS Cnt
FROM (
SELECT C1 AS C
UNION ALL
SELECT C2
UNION ALL
SELECT C3
UNION ALL
SELECT C4
UNION ALL
SELECT C5
UNION ALL
SELECT C6
) D
GROUP BY C
ORDER BY Cnt DESC
)
Select distinc * returns unique ROWS not unique values from fields.
You should compare each column's value with others. (Assuming column types are the same). For example, for a 4 column table you should do smoething like:
SELECT Col1, Col2, Col3, Col4 FROM MyTable WHERE
Col1 NOT IN (Col2,Col3,Col4) AND
Col2 NOT IN (Col3,Col4) AND
Col3 <> Col4
SELECT DISTINCT * FROM tablename
SELECT DISTINCT col FROM tabl
SELECT * FROM
mytable
WHERE mytable.col1 != mytable.col2 != mytable.col3 ...