Oracle SQL Nested Query - sql

Table Z has A-M columns:
I have to display columns A,C,F,G,K,L,M with following conditions:
a. Search for selected date range(column A is date column)
b. Display top 10 rows where K> 5000
c. If the above returns less than 10 rows then find remaining rows where L> 500
d. If both above results return less than total of 10 rows then find remaining rows where M>50
PS: Rows will be total of 10 made out of result from b,c and d

You should be able to use an analytic function
SELECT <<whatever you want>>
FROM (SELECT z.*,
row_number() over (order by case when k > 5000 then 1 else 2 end,
case when l > 500 then 1 else 2 end,
case when m > 50 then 1 else 2 end) rn
FROM z
WHERE a BETWEEN <<lower date>> and <<upper date>>)
WHERE rn <= 10

Related

SQL For each unique value in Column A, sum Column B. If sum is greater than 50, create Column C and add value "Y", else "N"

Seems simple, but I can't seem to wrap my head around it. I have the table below.
ID Total
1 20
1 30
1 30
2 10
2 10
For each unique value in 'ID' column, I want the sum of 'Total' column. If the sum of the total is greater than 50, create new column 'Result' and add value 'Y', if not then add value 'N'.
The result should look like this. Yes, I want to keep each row.
ID Total Result
1 20 Y
1 30 Y
1 30 Y
2 10 N
2 10 N
I'm stuck....
Use window functions:
select t.*,
(case when sum(total) over (partition by id) >= 50 then 'Y' else 'N' end)
from t;

Count rows according to 2 column with Group By

I have a database table of 3 columns
RecordID Deleted CardHolderID
1963 1 9
4601 1 9
6996 0 9
1532 1 11
1529 0 20
I want an sql query to output the sum of rows of Deleted column grouped by CardHolderID.
However query below outputs 2 columns for CardHolderID
select c.CardHolderID, c.Deleted, COUNT(*) as Sum
from Card c
group by c.Deleted, c.CardHolderID
CardHolderID Deleted Sum
9 0 1
9 1 2
20 0 1
11 1 1
I want to include 2 columns as Deleted0 (count of rows with Deleted column equal to 0) and Deleted1 (count of rows with Deleted column equal to 1)
CardHolderID Deleted0 Deleted1
9 1 2
20 1 0
11 1 1
How should be the SQL query for such a result?
Kind regards
Using conditional count:
select c.CardHolderID,
count( case when c.deleted > 0 then 1 else null end ) deleted0,
count( case when c.deleted = 0 then 1 else null end ) deleted1,
from Card c
group by c.CardHolderID
GROUP BY CardHolderID alone.
Use SUM(Deleted) to count the 1's.
Use SUM(1-deleted) to count the 0's.
select c.CardHolderID, sum(1-c.deleted) deleted0, sum(c.Deleted) deleted1
from Card c
group by c.CardHolderID
if you are using MSSQL
select DtlPivot.CardHolderID, isnull(DtlPivot.[0],0) as Deleted0, isnull(DtlPivot.[1],0) as Deleted1 from
(
select c.CardHolderID, c.Deleted, COUNT(*) as Total from Card c
group by c.Deleted, c.CardHolderID
) aa
PIVOT
(
sum(Total) FOR Deleted IN([0],[1])
)AS DtlPivot

SQL query to find the entries corresponding to the maximum count of each type

I have a table X in Postgres with the following entries
A B C
2 3 1
3 3 1
0 4 1
1 4 1
2 4 1
3 4 1
0 5 1
1 5 1
2 5 1
3 5 1
0 2 2
1 2 3
I would like to find out the entries having maximum of Column C for every kind of A and B i.e (group by B) with the most efficient query possible and return corresponding A and B.
Expected Output:
A B C
1 2 3
2 3 1
0 4 1
0 5 1
Please help me with this problem . Thank you
demo: db<>fiddle
Using DISTINCT ON:
SELECT DISTINCT ON (B)
A, B, C
FROM
my_table
ORDER BY B, C DESC, A
DISTINCT ON gives you exactly the first row for an ordered group. In this case B is grouped.
After ordering B (which is necessary): We first order the maximum C (with DESC) to the top of each group. Then (if there are tied MAX(C) values) we order the A to get the minimum A to the top.
Seems like it is a greatest n per group problem:
WITH cte AS (
SELECT *, RANK() OVER (PARTITION BY B ORDER BY C DESC, A ASC) AS rnk
FROM t
)
SELECT *
FROM cte
WHERE rnk = 1
You're not clear which A needs to be considered, the above returns the row with smallest A.
itseems to me you need max()
select A,B, max(c) from table_name
group by A,B
this will work:
select * from (SELECT t.*,
rank() OVER (PARTITION BY A,B order by C) rank
FROM tablename t)
where rank=1 ;

SQL combining of a COUNT with a WHERE in single query

Here is the data, call it table T
A B
-- --
1 14
2 15
3 16
4 1
4 3
4 6
4 9
4 12
4 15
I would like to get the value of A that has only one value and a B value of 15.
There are two rows where B=15 but there are 6 rows where A=4 and only one row where A=2.
So the correct SQL should return me the 2.
I have tried this but it returns both rows.
select A from T group by A,B having Count(A) = 1 and B = 15
This similarly fails:
select A from T where B = 15 group by A having count( A ) = 1
Try this:
select A
from T
group by A
having Count(A) = 1 and Max(B) = 15;
Your problem seems to be that you are grouping by both columns. You only want to group by A.
Admittedly, your query has group by A, T, but I think that is a typo, based on the described behavior.
You can check the count of B after grouping by A.
select A
from T
group by A
having Count(B) = 1 and max(B) = 15

SQL - how to replace my sum results in one number

I have a query that sums some columns
SELECT P, sum (K)
FROM table
GROUP BY P
and i want that if the sum is more than 1 i will have 1 in results. Meaning instead of:
P K
1 2
3 4
23 0
I will have:
P K
1 1
3 1
23 0
use CASE
SELECT P,
(CASE WHEN sum(K) > 0 THEN 1 ELSE 0 END) AS Result
FROM tableName
GROUP BY P
UPDATE
SQLFiddle Demo
Thanks to Luv
SELECT P, LEAST(1, sum (K))
FROM table
GROUP BY P
It sounds like there are 2 conditions sum(K) > 1 then you want want, the only option for sum(K) < 1 is 0. So this will give you that.