I need to write the query to find the max value from the table value.
Table structure as follows,
col col2 col3
1 a1 20150102
2 c1 20150201
3 a1 20150301
4 c1 20150101
I want the result as follows
output: table1
c1 = 20150201
a1 = 20150301
my query:
Select * from table1 where col3 = (select max(col3) from table1);
Use GROUP BY and the MAX function.
SELECT col2, MAX(col3)
FROM table1
GROUP BY col2
Output
col2 MAX(col3)
a1 20150301
c1 20150201
SQL Fiddle: http://sqlfiddle.com/#!9/73026/1/0
this way also we can do using Row_number
DECLARE #Table1 TABLE
(col int, col2 varchar(2), col3 int)
;
INSERT INTO #Table1
(col, col2, col3)
VALUES
(1, 'a1', 20150102),
(2, 'c1', 20150201),
(3, 'a1', 20150301),
(4, 'c1', 20150101)
;
select T.col2,T.col3 from #Table1 T
INNER JOIN (select RN from (select (ROW_NUMBER()OVER(PARTITION BY col2 ORDER BY col3))RN from #Table1)T GROUP BY T.RN )TT ON T.col = TT.RN
ORDER BY T.col2 DESc
Related
I have a table of two columns
Col1 Col2
A 1
A 2
A 3
B 1
B 2
B 3
Output I need is like this
Col1 Col2
A 1
A 1,2
A 1,2,3
B 1
B 1,2
B 1,2,3
Thank you in advance.
Here is a solution which would work for MySQL. It uses a correlated subquery in the select clause to group concatenate together Col2 values. The logic is that we only aggregate values which are less than or equal to the current row, for a given group of records sharing the same Col1 value.
SELECT
Col1,
(SELECT GROUP_CONCAT(t2.Col2 ORDER BY t2.Col2) FROM yourTable t2
WHERE t2.Col2 <= t1.Col2 AND t1.Col1 = t2.Col1) Col2
FROM yourTable t1
ORDER BY
t1.Col1,
t1.Col2;
Demo
Here is the same query in Oracle:
SELECT
Col1,
(SELECT LISTAGG(t2.Col2, ',') WITHIN GROUP (ORDER BY t2.Col2) FROM yourTable t2
WHERE t2.Col2 <= t1.Col2 AND t1.Col1 = t2.Col1) Col2
FROM yourTable t1
ORDER BY
t1.Col1,
t1.Col2;
Demo
Note that the only real change is substituting LISTAGG for GROUP_CONCAT.
with s (Col1, Col2) as (
select 'A', 1 from dual union all
select 'A', 2 from dual union all
select 'A', 3 from dual union all
select 'B', 1 from dual union all
select 'B', 2 from dual union all
select 'B', 3 from dual)
select col1, ltrim(sys_connect_by_path(col2, ','), ',') path
from s
start with col2 = 1
connect by prior col2 = col2 - 1 and prior col1 = col1;
C PATH
- ----------
A 1
A 1,2
A 1,2,3
B 1
B 1,2
B 1,2,3
6 rows selected.
I want get the count of colum3, but I want to group it by column1 and column2 whereby column2 has always the same (all) values of column2.
My current version: http://sqlfiddle.com/#!9/00d9d/1/0
Code:
CREATE TABLE table1
(`column1` varchar(2), `column2` varchar(2), `column3` varchar(2))
;
INSERT INTO table1
(`column1`, `column2`, `column3`)
VALUES
('aa', 'ba', 'ca'),
('aa', 'ba', 'cb'),
('aa', 'ba', 'cc'),
('aa', 'bb', 'ca'),
('aa', 'bb', 'cb'),
('aa', 'bc', 'ca'),
('aa', 'bc', 'cb'),
('aa', 'ba', 'ca'),
('ab', 'ba', 'cb'),
('ab', 'bc', 'ca')
;
My query:
SELECT
column1
,column2
,COUNT(column3)
FROM
table1
GROUP BY
column1
,column2
Result
column1 column2 COUNT(column3)
aa ba 4
aa bb 2
aa bc 2
ab ba 1
ab bc 1
Now is my question how can I ensure that in all column1 aggregations are the same values of column2? In case of the example I miss the
ab;bb;0
So I want that for every value of column1 I have the same set of values for column2. Which means in reality that a missing value gets filled up with 0 as count.
You have to first generate all allowed values (column1 x column2) and then left join this with your query. Your query will provide the count where it knows it, otherwise you will just get 0:
select base1.column1, base2.column2, ifnull(YourQuery.cnt, 0)
from (select distinct column1 from table1) as base1
cross join (select distinct column2 from table1) as base2
left join
(SELECT column1,column2,COUNT(column3) as cnt
FROM table1
GROUP BY column1,column2
) as YourQuery
on YourQuery.column1 = base1.column1 and YourQuery.column2 = base2.column2;
The idea is basically to get all the combination and use join or union to fill the gap, Here i am using union all.
SELECT
column1
,column2
,count(column3)
from (
select column1, column2, column3 from table1
union all
select column1,column2, null as column3
from (select distinct column1 from table1 ) all_c1
cross join ( select distinct column2 from table1) all_c2
)t group by column1, column2;
Using SQL Server 2008 tsql, I'm trying to remove ALL the records in a table when a set of values recur. So if my table looked like this:
idcol1col2
1 A 1
2 A 1
3 A 2
4 B 1
5 B 1
6 B 2
Rows 1, 2, 4, 5 would all be deleted.
;WITH d AS
(
SELECT col1, col2, c = COUNT(*) OVER
(PARTITION BY col1, col2 ORDER BY col1)
FROM dbo.yourtable
)
DELETE d WHERE c > 1;
In fact it can be slightly tidier:
;WITH d AS
(
SELECT id, c = COUNT(*) OVER
(PARTITION BY col1, col2 ORDER BY col1)
FROM dbo.yourtable
)
DELETE d WHERE c > 1;
And I'll fess up, I tested the above on SQL Server 2012, however I forgot to change the fiddle to SQL Server 2008. For versions prior to SQL Server 2012, here is one variation:
;WITH d AS
(
SELECT col1, col2
FROM dbo.yourtable AS t
GROUP BY col1, col2
HAVING COUNT(*) > 1
)
DELETE t --*
FROM dbo.yourtable AS t
WHERE EXISTS
(
SELECT 1 FROM d
WHERE col1 = t.col1 AND col2 = t.col2
);
You'd think it would be sufficient to just DELETE d; here but you get:
Msg 4403, Level 16, State 1, Line 2
Cannot update the view or function 'd' because it contains aggregates, or a DISTINCT or GROUP BY clause, or PIVOT or UNPIVOT operator.
Try this:
DELETE t
FROM dbo.yourTabe t
JOIN (
SELECT col1,col2,COUNT(1) cnt
FROM dbo.YourTable
GROUP BY col1, col2
HAVING COUNT(1)>1
) s
ON t.col1 = s.col1
AND t.col2 = s.col2
If you will look at the image above. I need to update this table for the null values of the TID which is column third in the table, with the values in between two rows that actually has value.
So in the above example, I need to have rows 44-57 as 040, row 60-87 as 077 etc. One pattern that could be used is that column 2 has INS in the string, which denotes that the value in column 3 is to be changed. So I was thinking about using DATA LIKE 'INS%' in some way.
Please let me know what you think of the problem and any possible solutions.
thanks!
DECLARE #x TABLE
(Column1 INT, Column2 VARCHAR(64), TID VARCHAR(10));
INSERT #x VALUES
(42, 'INS{whatever}', '040'),
(43, 'somethingelse', '040'),
(44, 'somethingelse', NULL),
(45, 'somethingelse', NULL),
(46, 'somethingelse', NULL),
(47, 'somethingelse', NULL),
(48, 'somethingelse', NULL),
(49, 'INS{whatever}', '077'),
(50, 'somethingelse', '077'),
(51, 'somethingelse', NULL),
(52, 'somethingelse', NULL);
;WITH x AS (SELECT i = Column1, TID, rn = ROW_NUMBER() OVER (ORDER BY Column1)
FROM #x WHERE Column2 LIKE 'INS%'
),
y AS (SELECT x.TID, s = x.i, e = COALESCE(x2.i, 2000000000)
FROM x LEFT OUTER JOIN x AS x2 ON x.rn = x2.rn -1
)
UPDATE src SET TID = y.TID
FROM #x AS src
INNER JOIN y ON src.Column1 > y.s AND src.Column1 < y.e;
SELECT * FROM #x;
This assumes that:
The first two columns in your sample were duplicated (I ignore the first listed)
Col1 is a primary key
Values are to be assigned as you described based on ascending values in Col1
Performance might be bad to very bad on large tables
Performance would improve with suitable indexing (on Col1 and Col3)
Substitute in your table and column names, and check for minor typos.
UPDATE MyTable
set Col3 = mt2.Col3
from MyTable mt
inner join (-- Get the "earlier" Col3 value for each row that has no value
select t1.Col1, max(t2.Col1) EarlierValueHere
from MyTable t1
inner join MyTable t2
on t2.Col1 < t1.Col1
and t2.Col3 is not null
group by t1.Col1
where t1.Col3 is null) earlier
on earlier.Col1 = mt.Col1
inner join MyTable mt2
on mt2.Col1 = earlier.EarlierValueHere
Another query you might use:
update t set TID = X.NonNullTID
from [YourTable] t
join
(select
t1.Column1, t1.Column2, t1.TID,
(select top 1 tid from [YourTable]
where TID is not null and Column1 <= t1.Column1
order by Column1 desc) as NonNullTID
from [YourTable] t1) X
on X.Column1 = t.Column1
I have a table in MySQL:
Col1 | Col2
a A
a B
c C
a B
i want to create a table like this:
col1 | col2 | freq
a A 0.33
a B 0.67
col1 is a specified item in Col1. col2 is distinct item that has occured with the specified item(i.e. a). freq column is the frequency of appearence of item in col2.
Can someone give me a hint of how to create such a query? Thanks a lot.
try this:
Select A.Col1, A.Col2, A.Count1 * 1.0 / B.Count2 As Freq
From (
Select Col1, Col2, Count(*) As Count1
From YourTableName
Group By Col1, Col2
) As A
Inner Join (
Select Col1, Count(*) As Count2
From YourTableName
Group By Col1
) As B
On A.Col1 = B.Col1
You can also use this which is coded in SQL server
DECLARE #Count INT;
SELECT #Count = COUNT(1) FROM YourTableName WHERE Col1 = 'a'
SELECT Col1, Col2, CAST(COUNT(1)* 1.00 /#Count AS DECIMAL(4,2) ) AS Frequency
FROM YourTableName
WHERE Col1 = 'a'
GROUP BY Col1, Col2
this way you have a better performance
With window functions
SELECT Col1, Col2, Count1*1.0 / Count2 AS freq
FROM (
SELECT
Col1,
Col2,
COUNT() OVER(PARTITION BY Col1, Col2) AS Count1,
COUNT() OVER(PARTITION BY Col1) AS Count2
FROM YourTableName
)
GROUP BY Col1, Col2