table join where - sql

Table1 t10 (id)
id
---
1
2
table t11(a1,a2,a3)
a1 a2 a3
----------
1 10 a
1 10 b
1 11 b
1 12 c
2 20 d
2 21 e
select * from t10 a,t11 b where a.id = b.a1
how to display
id a1 a2 a3
--------------
1 1 10 a
1 1 10 b //(not display this row)
1 1 11 b //(not display this row)
1 1 12 c //(not display this row)
2 2 20 d
2 2 21 e //(not display this row)
just get t11's random row
maybe display this
id a1 a2
----------
1 1 11 b
1 1 10 a //(not display this row)
1 1 10 b //(not display this row)
1 1 12 c //(not display this row)
2 2 20
2 2 21 //(not display this row)

select a1 as id, a1, min(a2) as a2
from t11
group by a1
will give you:
id a1 a2
----------
1 1 10
2 2 20

This seems almost like he wants something like FIRST/LAST from ms access.
This can ben done (very closely) in Sql Server using
DECLARE #Table TABLE(
id INT,
a1 INT,
a2 INT
)
INSERT INTO #Table (id,a1,a2) SELECT 1, 1, 11
INSERT INTO #Table (id,a1,a2) SELECT 1, 1, 10
INSERT INTO #Table (id,a1,a2) SELECT 1, 1, 12
INSERT INTO #Table (id,a1,a2) SELECT 2, 2, 20
INSERT INTO #Table (id,a1,a2) SELECT 2, 2, 21
SELECT *
FROM #Table t
WHERE a2 = (SELECT TOP 1 a2 FROM #Table WHERE id = t.id AND a1 = t.a1)

This is the answer:
SELECT *
FROM t10 a, (
SELECT * FROM (
SELECT b.*, ROW_NUMBER() OVER(PARTITION BY a10 ORDER BY a10) as rn
FROM t11 b
) WHERE rn =1) b
WHERE a.id = b.a10(+)

Related

To create a column Summing the values from another column in the same view

View:
A | B
10 1
15 2
12 3
5 2
2 1
2 1
Output View:
A | B | C
10 1 14
15 2 20
12 3 12
5 2 20
2 1 14
2 1 14
I need to sum the values from column A based on column B. So, all the values from column B having value 1 extract values from column A and then sum it to column C.
I don't see the point, but:
SELECT t.a
,t.b
,sumtab.c
FROM [yourtable] t
INNER JOIN (
SELECT t.b
,sum(t.a) AS C
FROM [yourtable] t
GROUP BY t.b
) AS sumtab
ON t.b = sumtab.b
You could use SUM() OVER like this
DECLARE #SampleData AS TABLE
(
A int,
B int
)
INSERT INTO #SampleData
(
A,
B
)
VALUES
( 10, 1),
( 15, 2),
( 12, 3),
( 5 , 2),
( 2 , 1),
( 2 , 1)
SELECT *,
sum(sd.A) OVER(PARTITION BY sd.B) AS C
FROM #SampleData sd
Returns
A B C
-----------
10 1 14
2 1 14
2 1 14
15 2 20
5 2 20
12 3 12

column update in sequence

I have a table that contains 3 columns as below:
col1 col2 col3
---- ---- ----
1 1 null
2 2 null
3 3 null
4 1 null
5 1 null
6 1 null
7 2 null
ETC
I need to update a third column in the same table as follows:
col1 col2 col3
---- ---- ----
1 1 1
2 2 1
3 3 1
4 1 2
5 1 3
6 1 4
7 2 4
The logic behind the update is that each time the 2nd column contains a 1 in it, the third has to increment. The first column is just a sequential integer column.
You can use the row_number analytical function to number the rows with col2 = 1 sequentially and then use a subquery to find to closest value with a lower col1 for the other rows.
So given a test table like this:
create table t (c1 int, c2 int, c3 int);
insert t (c1, c2) values
(1, 1),
(2, 2),
(3, 3),
(4, 1),
(5, 1),
(6, 1),
(7, 2);
A query like this:
;with cte as (
select t.c1, t.c2, x.c3
from t
left join (
select c1, c2, row_number() over (partition by c2 order by c1) c3
from t
where c2 = 1
) x on t.c1 = x.c1
)
update t
set t.c3 = coalesce(cte1.c3,(select max(cte2.c3) from cte cte2 where cte2.c1 < cte1.c1))
from cte cte1
where t.c1 = cte1.c1
Will give the following result:
c1 c2 c3
1 1 1
2 2 1
3 3 1
4 1 2
5 1 3
6 1 4
7 2 4
Another, possibly faster, way to do this would be:
update t1 set c3 = (select count(*) from t where c2 = 1 and c1 <= t1.c1) from t t1

How to select all records after a certain record within groups in sql?

Given the following table structure
Col1, Col2, EventType, DateTime
How can I select the records per grouping of Col1, Col2 that occur after the top record where EventType = 3 for that particular group of Col1, Col2.
For example with the following data
Col1, Col2, EventType, DateTime
A B 1 2012-1-1
A B 3 2011-1-1
A B 1 2010-1-1
C D 1 2012-1-1
C D 2 2011-1-1
C D 2 2010-1-1
C D 3 2009-1-1
C D 2 2008-1-1
C D 3 2007-1-1
C D 1 2006-1-1
C D 2 2005-1-1
I want to select
Col1, Col2, EventType, DateTime
A B 1 2012-1-1
C D 1 2012-1-1
C D 2 2011-1-1
C D 2 2010-1-1
You can use the max function over a subquery:
SELECT Col1, Col2, EventType, DateTime
FROM theTable A
WHERE DateTime >
(SELECT MAX(DateTime)
FROM theTable SUB
WHERE EventType = 3
AND SUB.COL1 = A.COL1
AND SUB.COL2 = A.COL2)
It is possible to solve this using ROW_NUMBER():
Partition the rows into groups of (Col1, Col2) and rank rows in every group in the ascending order of DateTime.
Col1 Col2 EventType DateTime EventRank
---- ---- --------- -------- ---------
A B 1 2012-1-1 3
A B 3 2011-1-1 2
A B 1 2010-1-1 1
C D 1 2012-1-1 8
C D 2 2011-1-1 7
C D 2 2010-1-1 6
C D 3 2009-1-1 5
C D 2 2008-1-1 4
C D 3 2007-1-1 3
C D 1 2006-1-1 2
C D 2 2005-1-1 1
Also, partition the rows by (Col1, Col2, EventType) and rank them in the descending order of DateTime.
Col1 Col2 EventType DateTime EventRank EventSubRank
---- ---- --------- -------- --------- ------------
A B 1 2012-1-1 3 1
A B 3 2011-1-1 2 1
A B 1 2010-1-1 1 2
C D 1 2012-1-1 8 1
C D 2 2011-1-1 7 1
C D 2 2010-1-1 6 2
C D 3 2009-1-1 5 1
C D 2 2008-1-1 4 3
C D 3 2007-1-1 3 2
C D 1 2006-1-1 2 2
C D 2 2005-1-1 1 4
Select a subset where EventType = 3 AND EventSubRank = 1.
Col1 Col2 EventType DateTime EventRank EventSubRank
---- ---- --------- -------- --------- ------------
A B 3 2011-1-1 2 1
C D 3 2009-1-1 5 1
Use it as a filter by joining it back to the ranked row set and selecting rows of the latter whose EventRank values are greater than the corresponding ones in the subset.
Here's a complete query:
WITH ranked AS (
SELECT
*,
EventRank = ROW_NUMBER() OVER (PARTITION BY Col1, Col2 ORDER BY DateTime ASC ),
EventSubRank = ROW_NUMBER() OVER (PARTITION BY Col1, Col2, EventType ORDER BY DateTime DESC)
FROM atable
),
filtered AS (
SELECT *
FROM ranked
WHERE EventType = 3
AND EventSubRank = 1
)
SELECT
r.Col1,
r.Col2,
r.EventType,
r.DateTime
FROM ranked
INNER JOIN filtered f
ON r.Col1 = f.Col1
AND r.col2 = f.Col2
AND r.EventRank > f.EventRank
;
select Col1, Col2, EventType, DateTime
From yourtable A,
(select Col1, Col2 from yourtable group by Col1, Col2) B
where A.EventType<3 and A.Col1 =B.Col1 And A.Col2=B.Col2
To get the expected result
Select Col1, Col2, EventType, DateTime from table where EventType<3
Try This,
Select a.* FROm yourtable A JOIN
(SELECT * FROM yourTable WHERE EventType=3) b
ON A.Col1=B.Col1
AND A.Col2 = B.Col2
WHERE A.dateTime>B.DateTime

oracle sql group count

SELECT a,b,count(*)
FROM t
GROUP BY rollup(a,b)
result:
a1, b1, 10
a1, b2, 90
a1, , 100
i need:
a1, b1, 10, 100
a1, b2, 90, 100
how?
This table simulates your situation:
SQL> create table t (a,b)
2 as
3 select 'a1', 'b1'
4 from dual
5 connect by level <= 10
6 union all
7 select 'a1', 'b2'
8 from dual
9 connect by level <= 90
10 /
Table created.
Your result with only three rows misses the grand total, so that's a little inaccurate: rollup(a,b) results in 3 grouping sets with 4 rows.
SQL> select a
2 , b
3 , count(*)
4 from t
5 group by rollup(a,b)
6 /
A B COUNT(*)
-- -- ----------
a1 b1 10
a1 b2 90
a1 100
100
4 rows selected.
With a regular group by and an analytic function on top, you can achieve your desired result set:
SQL> select a
2 , b
3 , count(*)
4 , sum(count(*)) over (partition by a)
5 from t
6 group by a
7 , b
8 /
A B COUNT(*) SUM(COUNT(*))OVER(PARTITIONBYA)
-- -- ---------- -------------------------------
a1 b2 90 100
a1 b1 10 100
2 rows selected.
Regards,
Rob.
Use:
SELECT t.a,
t.b,
COUNT(*),
(SELECT COUNT(*)
FROM YOUR_TABLE
GROUP BY t.a)
FROM YOUR_TABLE t
GROUP BY t.a, t.b

Oracle query to select rows with unique code

I have a table like this
C1 C2 C3 Code
1 2 3 33
1 2 3 34
2 4 1 14
1 2 3 14
i want to select only those record whose code is appearing only in single row. ie, in this case rows with code 33 and 34.. as they appear only once in this table.
How can i write a query for that
If you want only one pass over your data, then you can use this query:
SQL> create table mytable (c1,c2,c3,code)
2 as
3 select 1, 2, 3, 33 from dual union all
4 select 1, 2, 3, 34 from dual union all
5 select 2, 4, 1, 14 from dual union all
6 select 1, 2, 3, 14 from dual
7 /
Table created.
SQL> set autotrace on
SQL> select max(c1) c1
2 , max(c2) c2
3 , max(c3) c3
4 , code
5 from mytable
6 group by code
7 having count(*) = 1
8 /
C1 C2 C3 CODE
---------- ---------- ---------- ----------
1 2 3 33
1 2 3 34
2 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 FILTER
2 1 SORT (GROUP BY)
3 2 TABLE ACCESS (FULL) OF 'MYTABLE'
Regards,
Rob.
SELECT C1, C2, C3, Code FROM tablename
WHERE Code IN
(
SELECT Code FROM tablename
GROUP BY Code
HAVING count(Code) = 1
)
select C1, C2, C3, Code
from tablename T1
where not exists ( select T2.exclude
from tablename T2
where T2.Code = T1.Code
and T2.rowid <> T1.rowid
)
PS. Watch out for NULL values in the Code column