How to get the desired results for this scenario [SQL] - sql

I need to build a query for the following scenario :
Input table:
col1 col2 col3 col4
-------------------------------
1 2 a pi
1 4 a ci
1 2 a ci
2 3 a pi
2 4 a ci
1 3 a ci
1 3 a pi
Logic required:
Fetch all the records from the input table except for the records matching below condition.
If value of group (a,b) is same for multiple rows, then only keep the row that has d='pi'
Ex: for row 1 & 3 value of (a,b) = (1,2) we need to keep only row 1 that has d='pi'.
Final desired output:
col1 col2 col3 col4
---------------------------------
1 2 a pi
1 4 a ci
2 3 a pi
2 4 a ci
1 3 a pi
Please help me out.

You can approach this with analytic functions, if you like:
select a, b, c, d
from (select t.*,
row_number() over (partition by a, b
order by (case when d = 'pi' then 1 else 2 end)
) as seqnum
from table t
) t
where seqnum = 1;

use a where not exist construct:
SELECT * FROM tab1 t
WHERE NOT EXISTS (SELECT 1 FROM tab1
WHERE t.a = a AND t.b = b)
OR d ='pi'

Related

SELECT multiple columns with conditions from a table that contains only one VALUE column and two counters (X,Y)

I am using SQL Server, and i want to be able to select 3 different columns from one and only Table column (DATA) (under certain conditions)
Here is the Initial Table MYTABLE that i want to exploit :
Table_id X Y DATA
22 0 0 DEV
22 0 1 TRAD
22 1 0 5
22 1 1 2
22 2 0 300
22 2 1 100
The result that i want to have is the following :
COL1 COL2 COL3
DEV 5 300
TRAD 2 100
and my 3 distinct SQL queries are as follow :
SELECT t1.DATA as "COL1" from MYTABLE t1 where t1.Table_id = 22 AND t1.X = 0
GIVES THE FOLLOWING RESULT :
COL1
DEV
TRAD
SELECT t2.DATA as "COL2" from MYTABLE t2 where t2.Table_id = 22 AND t2.X = 1
GIVES THE FOLLOWING RESULT :
COL2
5
2
SELECT t3.DATA as "COL3" from MYTABLE t3 where t3.Table_id = 22 AND t3.X = 2
GIVES THE FOLLOWING RESULT :
COL3
300
100
Can anyone please help me to merge those 3 queries into one and select the 3 columns from the DATA column ?
You can use conditional aggregation:
select max(case when x = 0 then data end) as col1,
max(case when x = 1 then data end) as col2,
max(case when x = 2 then data end) as col3
from mytable
where table_id = 22
group by y

Count the number of unique values with at least k occurrences per group in postgres

I have a table with 3 columns that looks like this :
ID | obs_type | Value
1 A 0.1
1 A 0.2
1 B 0.4
2 B 0.5
2 C 0.2
2 C 0.3
3 B 0.1
I want to have the count of IDs with at least k observations in each group Type.
In the example above, if k = 2 (at least 2 observations of the same ID to be counted), I would like to have :
obs_type | count
A 1
B 0
C 1
As there is a single ID with two observations of type A and single ID with two observations of type C.
There are no ID with two observations of type B.
For k = 1, I just do :
SELECT obs_type, COUNT(DISTINCT ID ) FROM table_x GROUP BY obs_type;
But I'm looking for a solution that would work for arbitrary k.
Thanks !!!!
Do the aggregation in two steps:
k = 2 here:
select count(case when cnt >= 2 then cnt end), obs_type
from
(
select count(*) cnt, obs_type
from table_x
group by id, obs_type
) dt
group by obs_type
The derived table (subquery) returns:
cnt obs_type
================ ========
2 A
1 B
1 B
2 C
1 B
Then use a case expression to do conditional aggregation, and you'll get:
SQL>select count(case when cnt >= 2 then cnt end), obs_type
SQL&from
SQL&(
SQL& select count(*) cnt, obs_type
SQL& from table_x
SQL& group by id, obs_type
SQL&) dt
SQL&group by obs_type;
obs_type
==================== ========
1 A
0 B
1 C
3 rows found

oracle sql - N number of rows for for distinct value i

Suppose I have TableA w/ ID column:
TableA
ID
1
2
3
I'm hoping to get N rows returned for each distinct id in TableA
(example below is for N=3)
EXPECTED OUTPUT
ID SEQ
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
Is this possible w/ a single SQL statement?
Thanks!!
To get only rows with single ID
SELECT * FROM tab_name WHERE col1 = N ORDER BY col2 [DESC]
To Get how many records under each id
SELECT id, count(*) as count FROM tab_name GROUP BY id
To get specific number of rows per specific ID
SELECT *
FROM
(SELECT id, col2, ROW_NUMBER() OVER(PARTITION BY t.id ORDER BY col3) colX
FROM tab_name t) outerT
WHERE
outerT.colX < N + 1

How to check Oracle column values are all the same for a specific ID?

I am trying to figure out the best way to determine, for a specific ID within an Oracle 11g table that has 5 columns and say 100 rows against this ID, if all the column values are the same for these five columns.
For example:
Table Name: TABLE_DATA
Columns:
TD_ID ID COL1 COL2 COL3 COL4 COL5
-----------------------------------------------------------------------
1 1 1 0 3 2 0
2 1 1 0 3 2 0
3 1 1 0 3 2 0
4 1 1 0 3 2 0
5 1 1 0 3 2 0
6 1 1 0 3 2 0
So based on the above example which is just showing 6 rows for now against the ID:1, I want to check that for all COL1, COL2, COL3, COL4 and COL5 values where ID = 1, tell me if all the values are the same from the very first row right down to the last – if so, then return ‘Y’ else return ‘N’.
Given the above example, the result would be ‘Y’ but for instance, if TD_ID = 5 and COL3 = 4 then the result would be ‘N’, as all the column values are not the same, i.e.:
TD_ID ID COL1 COL2 COL3 COL4 COL5
-----------------------------------------------------------------------
1 1 1 0 3 2 0
2 1 1 0 3 2 0
3 1 1 0 3 2 0
4 1 1 0 3 2 0
5 1 1 0 4 2 0
6 1 1 0 3 2 0
I’m just not sure what the fastest approach to determine this is, as the table I am looking at may have more than 2000 rows within the table for a specific ID.
You may also try this :
Select ID
, case when count(distinct COL1 || COL2 || COL3 || COL4 || COL5) > 1
then 'N'
else 'Y' end RESULT
From TABLE_DATA
Group by id;
In this way you group by id and counts how many distinct combination are there.
If only 1 , so all the rows have the same set of values, otherwise it don't.
See if the following is fast enough for you:
SELECT ID, CASE WHEN COUNT(*) > 1 THEN 'No' ELSE 'Yes' END As "Result"
FROM (SELECT DISTINCT ID, COL1, COL2, COL3, COL4, COL5
FROM Table_Data) dist
GROUP BY ID
Here's a little query, you might wanna try out (eventually, you just could try figuring out a better MINUS statement for you):
SELECT
CASE
WHEN ( -- select count of records from a subquery
SELECT
COUNT(1)
FROM
( -- select all rows where id = 1
SELECT
td.col1
,td.col2
,td.col3
,td.col4
,td.col5
FROM
table_data td
WHERE
td.id = 1
MINUS -- substract the first row of the table with id = 1
SELECT
td.col1
,td.col2
,td.col3
,td.col4
,td.col5
FROM
table_data td
WHERE
td.id = 1
AND ROWNUM = 1
)
) = 0 -- check if subquery's count equals 0
AND EXISTS ( -- and exists at least 1 row in the table with id = 1
SELECT
1
FROM
table_data td
WHERE
td.id = 1
AND ROWNUM = 1
) THEN 'Y'
ELSE 'N'
END AS equal
FROM
dual

Clause ORDER BY

I have a problem with a select in sql server, i have this table with 2 columns:
a 2
b 1
c 100
d 1
a 100
b 1
c 2
d 1
I want ordered it based on the first column,in this way:
a 2
a 100
b 1
b 1
c 2
c 100
d 1
d 1
But then j want the rows with secondcolumn=100 be moved at the bottom,so:
a 2
b 1
b 1
c 2
d 1
d 1
a 100
c 100
I have tried with clause ORDER BY column1 ASC, (column2=100) ASC,but it didnt work!
Thankyou and greetings.
Actually, you want the rows with 100 in the second column moved to the bottom first, and then ordered by the first column:
order by (case when col2 = 100 then 1 else 0 end),
col1
Use the CASE expression as below
SELECT *
FROM tab
ORDER BY CASE
WHEN column2 = 100 THEN 1
ELSE 0
END ASC,
column1 asc
SELECT *
FROM table1
ORDER BY
CASE
WHEN col2>=100 THEN 1
ELSE 0
END,
col1,
col2
SQLFiddle Example