Find Average from recent most data when there are multiple - sql

Hi I need to find out a way to find average on data set when there multiple values but consider a specific value based on recent most
Table 1
ColumnA ColumnB ColumnC
A 3 07/21/2017
A 2 08/08/2017
B 1 07/22/2017
Calculate averae of ColumnB
It should 2 from A, 1 from B, which should be (2+1)/2 =1.5 and not (3+2+1)/3=2. The criteria is based on recent most time stamp of each category of columnA

I would use row_number():
select avg(columnB * 1.0)
from (select t.*,
row_number() over (partition by columnA order by columnC desc) as seqnum
from t
) t
where seqnum = 1;

http://sqlfiddle.com/#!6/daea4/3
Select
ColumnA, Avg(ColumnB)
from
table1
group by
ColumnA

Related

Filtering grouping records based on flags

Requirement:
Table data:
Col A
Col B
N
123
N
456
Y
456
Required data:
Col A
Col B
N
123
Y
456
Can someone help me which method I should use here to filter records.
I am grouping this data depends upon multiple fields.
After grouping I need to take single row for Col B.
Eg. Col B = 123 has only 1 record so we need to fetch that.
And for col B = 456, we have 2 records so in that case we just need to take records which is col A = Y
Thanks in advance
I have tried analytical function here but it's not working as expected
This answer assumes that your logic is to return the yes flag in cases where a B group have 2 records. We can use ROW_NUMBER here:
WITH cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY ColB ORDER BY ColA DESC) rn
FROM yourTable t
)
SELECT ColA, ColB
FROM cte
WHERE rn = 1;
we just need to take records which is col A = Y
If you want to take records (plural) for each col_b then use the RANK or DENSE_RANK analytic functions:
SELECT ColA,
ColB
FROM (
SELECT t.*,
RANK() OVER (PARTITION BY ColB ORDER BY ColA DESC) AS rnk
FROM table_name t
)
WHERE rnk = 1;
After grouping I need to take single row for Col B.
If you only want a single row per col_b then use the ROW_NUMBER analytic function (and if the priority cannot be sorted alphabetically then you can use a CASE expression):
SELECT ColA,
ColB
FROM (
SELECT t.*,
ROW_NUMBER() OVER (
PARTITION BY ColB
ORDER BY CASE ColA WHEN 'Y' THEN 0 ELSE 1 END
) AS rn
FROM table_name t
)
WHERE rn = 1;

How to implement conditional select in sql query?

How to fetch every 10th row from a table i.e. 10th,20th etc. But if there are less than 10 rows in that table, It should fetch the last row.
This can be an advance form of this query present in this question -
How can I select 10th, 20th, 30th ... row of the result of another select query
I have done something like this for selecting every 10th row -
select case_id
from
(select case_id,rownum as seq
from table
where from = 'A' and to ='B'
order by ID
)
where mod(seq,10) = 0
But if there are less than 10 rows in the result of inner query, It should fetch the last row.
OBS: database - Oracle 12c
SELECT ColumnA,
ColumnB,
ColumnC
FROM (
SELECT ROWNUM rn,
COUNT(*) OVER ( ORDER BY NULL ) mx,
q.ColumnA,
q.ColumnB,
q.ColumnC
FROM (
SELECT ColumnA,
ColumnB,
ColumnC
FROM your_table
ORDER BY ColumnA
) q
)
WHERE MOD( rn, 10 ) = 0
OR ( mx = rn AND mx < 10 );

SQL Duplicates multi criteria selection

I am trying to create a query that removes duplicates based multiple rules.
Some sample data:
Column A: Column B:
One Apple
One Pear
Two Apple
Two Mango
Three Pear
Four Mango
Five Plum
Six Mango
Zero Banana
Essentially what I have been rattling about is that I would like the query to return the distinct pairs based upon duplicates from each column. Meaning that the if there is a duplicate in A, all entries are removed based upon the column duplicates(example, two and two would remove two-apple, two-mango). The same logic for B(ex, apple apple and mango mango being taken out) So the final results would be:
Column A: Column B:
Three Pear
Zero Banana
Five Plum
Any pointers would be great. I am on SQL Server. Thank you.
You could join back on the table and then select rows that have no matches (e.g. no duplicates).
SELECT a, b
FROM my_table source
LEFT JOIN my_table a_dups
ON source.a = a_dups.a
AND source.b <> a_dups.b
LEFT JOIN my_table b_dups
ON source.b = b_dups.b
AND source.a <> b_dups.a
WHERE a_dups.a IS NULL
AND b_dups.b IS NULL
Typing this outside IDE so pardon SQL errors but hopefully should give you an idea.
You can use a windowing functions to get the count of the each field and then just check that the count is one for both. Like this:
SELECT ColumnA, ColumnB
FROM (
SELECT ColumnA, ColumnB,
COUNT(*) OVER (PARTITION BY ColumnA) as ACount,
COUNT(*) OVER (PARTITION BY ColumnB) as BCount
FROM TABLE
) X
WHERE ACount = 1 AND BCount = 1
Here it goes:
Creating sample data set:
CREATE TABLE #temp (ColumnA varchar(20), ColumnB varchar(20))
INSERT INTO #temp
VALUES('One','Apple'),
('One','Pear'),
('Two','Apple'),
('Two','Mango'),
('Three','Pear'),
('Four','Mango'),
('Five','Plum'),
('Six','Mango'),
('Zero','Banana');
Showing full data set:
SELECT * FROM #temp;
using Common Table expression with patrition by to identify duplicates in both columns:
WITH CTE AS (SELECT *,ROW_NUMBER() OVER (PARTITION BY ColumnA ORDER BY ColumnA ) AS rn1, ROW_NUMBER() OVER (PARTITION BY ColumnB ORDER BY ColumnB ) AS rn2 FROM #temp)
SELECT * FROM CTE WHERE ColumnA NOT IN (SELECT ColumnA FROM CTE WHERE rn1 <> 1) AND ColumnB NOT IN (SELECT ColumnB FROM CTE WHERE rn2 <> 1)
Showing result after:
SELECT * FROM #temp;

Group BY on Condition basis

I have data in following way....
ColumnA ColumnB
7675 22838
7675 24907
7675 NULL
I want the results in following way.....
ColumnA ColumnB
7675 2 (need total count for Not Null value)
7675 0 (need count 0 for NULL value)
SELECT ColumnA, COUNT(ColumnB) ColumnB
FROM YourTable
GROUP BY ColumnA
UNION ALL
SELECT ColumnA, 0
FROM YourTable
WHERE ColumnB IS NULL
GROUP BY ColumnA
You could introduce a calculated column indicating whether ColumnB is null or not and use it as a grouping criterion together with ColumnA:
SELECT
t.ColumnA,
ColumnB = COUNT(t.ColumnB)
FROM
dbo.YourTable AS t
CROSS APPLY
(SELECT CASE WHEN t.ColumnB IS NULL THEN 1 ELSE 0 END) AS x (SubGroup)
GROUP BY
t.ColumnA,
x.SubGroup
ORDER BY
t.ColumnA,
x.SubGroup
;
The COUNT(t.ColumnB) expression would always be NULL for a null subgroup, and for the corresponding non-null subgroup it would return the number of the non-null entries.
select columnA,
count(columnB) as non_null_count,
sum(columnB is null) as null_count
from your_table
group by ColumnA
you could easily do with a count and sum which may be faster if there are a lot of rows rather than selecting all of the rows twice with a UNION
SELECT columna, columnb, SUM(mycount)
FROM
( SELECT *, COUNT(columnb) as mycount
FROM test
GROUP BY columnb
)t
GROUP BY mycount
ORDER BY CASE WHEN mycount = 0 THEN 1 ELSE 2 END DESC;
Fiddle Demo

advice needed for SQL query

Can some one help to provide the SQL query should be used to pull out the "columna" value which has max number "columnb" value as "Active". Means in columnb there is a value "Active" , I want to pull the columna value which has max of value Active n columnb.
I am looking output to be columna = M1 and Count = 4
columna columnb
M1 Active
M1 Active
M1 Active
M1 Active
M2 failed
M2 failed
M2 failed
M3 pending
M3 pending
M3 pending
The results you request would be produced by:
SELECT columna,COUNT(*)
FROM Table
WHERE columnb = 'Active'
GROUP BY columna
SELECT top 1 columna,COUNT(*) as cnt
FROM Table1
WHERE columnb = 'Active'
GROUP BY columna
order by cnt desc
FIDDLE
SELECT columna,count(*) FROM TABLE_NAME where columnb = "Active" GROUP BY columna
Syntax is slightly different between RDMBS-es, but logic remains. Filter your rows based on columnb, group them by columna, order them on count(*) and select top 1
SQL Server:
SELECT TOP 1 columna, COUNT(*) AS Count
FROM YourTable
WHERE columnb = 'Active'
GROUP BY columna
ORDER BY COUNT(*) DESC
SQLFiddle DEMO
MySQL:
SELECT columna, COUNT(*) AS Count
FROM YourTable
WHERE columnb = 'Active'
GROUP BY columna
ORDER BY COUNT(*) DESC
LIMIT 1
SQLFiddle DEMO