Simply by the Query - sql

Table name is group. Column name is groupno,name,grouprefno,detail,undergroupno
Sample data of group
groupno name grouprefno detail undergroupno
1 A 001 abc 0
2 B 002 cde 0
3 AA 001001 abc 1
4 AC 001002 abc 1
5 AAA 001001001 DDD 3
6 DDD 001001002 ddd 3
7 www 001002001 223 4
8 eee 001002002 222 4
Now i want to get rows which name's are AA, AC and which are comes under the AA,AC
So i tried like this
select no from group where substring(grouprefno,1,
(select length(grouprefno) from group where name ='AA'
))=(select grouprefno from group
where name ='AA' ) union all select no from group where substring(grouprefno,1,
(select length(grouprefno) from group where name ='AC'
))=(select grouprefno from group
where groupname ='AC' )
Its Work Fine, But i want another solution because it has 2 sub query's in side of single query. It has any other feasible solution?
Am using postgresql 9.1

Try:
WITH q AS(
SELECT *
FROM Table1
WHERE name IN ('AA','AC')
)
SELECT * FROM q
UNION ALL
SELECT * FROM Table1 t
WHERE t.undergroupno IN (
SELECT groupno FROM q
)
Demo: http://sqlfiddle.com/#!12/fce65/3

Related

oracle sql to find the rows with one or more duplicate results in a same table

I have the below sample data set and I'm trying to come up with a query to find one or more duplicate rows from the same table
TABLE A: with 2 columns as below
CODE_NAME, RESULT
ABC 1
BBC 1
ZZZ 5
ZZZ 6
ZZZ 7
KBC 2
ZBC 2
CCC 2
XYZ 3
MNC 4
And my output should give all the unique rows with duplicate values in the result column such as below
CODE_NAME, RESULT
ABC 1
BBC 1
KBC 2
ZBC 2
CCC 2
i tried below but its not giving me correct result
select A t1, A t2
where A.result = b.result
and a.code_name <> b.code_name
Appreciate other suggestions.
You can use exists:
select t.*
from t
where exists (select 1
from t t2
where t2.result = t.result and t2.code_name <> t.code_name
);
For performance on a large dataset, you want an index on (result, code_name).
You might find it more convenient to have one row per duplicated result:
select result,
listagg(code_name, ',') within group (order by code_name)
from t
group by result
having count(*) > 1;

How to get Oracle to return unique results in a one to many relationship tables with a left join

I have a three tables
Table 1
Id Department
1 A
2 B
3 C
4 D
Table 2
Id DepartId Name
1 1 ABC
2 1 DEF
3 1 ASD
4 2 FGH
5 2 HJK
6 3 ZXC
Table 3
Id Depart Area
1 A pp
2 B
3 C nn
4 D oo
I need the result
Id Depart Name Area
1 A ABC pp
2 B FGH Null
3 C ZXC nn
4 D NULL oo
I need one matching entry from table 2 and table 3 to corresponding entry in the table 1
Do a left join to also get t1 rows without any reference in the t2 table. GROUP BY to get only 1 row per Department.
select t1.id, t1.Department, min(t2.Name)
from t1
left join t2 on t1.id = t2.DepartId
group by t1.id, t1.Department
I think I would do this with a correlated subquery:
select t1.*,
(select t2.name
from t2
where t1.id = t2.DepartId and rownum = 1
) as t2name
from t1;
This saves the overhead of an aggregation. An index on t2(DepartId, name) is optimal for this query.
by the way not the answer to your specific question but if instead of just one you want all the names you can use listagg
SELECT t1.id,
department,
LISTAGG (name, ',') WITHIN GROUP (ORDER BY name) names
FROM t1, t2
WHERE t1.id = t2.departId(+)
GROUP BY t1.id, department
ORDER BY 1
ID Department Names
1 A ABC,ASD,DEF
2 B FGH, HJK
3 C ZXC
4 D

Taking Sample in SQL Query

I'm working on a problem which is something like this :
I have a table with many columns but major are DepartmentId and EmployeeIds
Employee Ids Department Ids
------------------------------
A 1
B 1
C 1
D 1
AA 2
BB 2
CC 2
A1 3
B1 3
C1 3
D1 3
I want to write a SQL query such that I take out 2 sample EmployeeIds for each DepartmentID.
like
Employee Id Dept Ids
B 1
C 1
AA 2
CC 2
D1 3
A1 3
Currently I am writing the query,
select
EmployeeId, DeptIds, count(*)
from
table_name
group by 1,2
sample 2
but it gives me total two rows.
Any help?
If the number of departments i know and small you could do a stratified sampling:
select *
from table_name
sample
when DeptIds = 1 then 2
when DeptIds = 2 then 2
when DeptIds = 3 then 2
end
Otherwise a combination of RANDOM and ROW_NUMBER:
select *
from
(
sel EmployeeId, DeptIds, random(1,10000000) as rand
from table_name
) as dt
qualify
row_number()
over (partition by DeptIds
order by rand) <= 2

SQL. How to select multiple rows by using the MIN and GROUP BY

ID UserId Name Amount RewardId
----------------------------
1 1 James 10.00 1
2 1 James 10.00 2
3 1 James 10.00 3
4 2 Dave 20.00 1
5 2 Dave 20.00 3
6 3 Lim 15.00 2
I'm trying to insert to another table, and this is the result that i'm struggling with:
Tbl1ID RewardId
------------------
1 1
1 2
1 3
4 1
4 3
6 2
I'm trying to get the MIN(ID) of each person and select all the RewardId that belong to that person.
You could do a simple self join to get the minimum id value per userid/rewardid combination;
SELECT MIN(a.id) Tbl1ID, b.RewardId
FROM mytable a
JOIN mytable b
ON a.name = b.name
GROUP BY b.userid, b.rewardid
ORDER BY tbl1id, rewardid;
An SQLfiddle to test with.
If you are running SQL Server 2008+, you can simplify it by using Window Function.
INSERT INTO AnotherTable (Tbl1ID, RewardID)
SELECT MIN(ID) OVER (PARTITION BY Name),
RewardID
FROM SourceTable
SQLFiddle Demo
Try this
SELECT tbl1id,RewardID From
table1 S JOIN
(
SELECT MIN(ID) as tbl1id,Name FROM table1 GROUP BY Name
) T ON T.Name = S.Name
ORDER BY tbl1id
FIDDLE DEMO
Output:
Tbl1ID RewardId
----------------
1 1
1 2
1 3
4 1
4 3
6 2
If you want insert into new table then try this out
Insert into Newtable (tbl1id,RewardID)
SELECT tbl1id,RewardID from
table1 S JOIN
(
SELECT MIN(ID) as tbl1id,Name
FROM table1
GROUP BY Name
) T ON T.Name = S.Name
ORDER BY tbl1id;
FIDDLE DEMO

T-SQL recursive query - how to do it?

I have a table with self referencing relation,
ID parentID UserId Title
1 null 100 A
2 1 100 B
3 2 100 C
4 2 100 D
5 null 100 E
6 5 100 F
I want to update UserId from 100 to 101 for all records with ID=1 and its children, so I want to have
ID parentID UserId Title
1 null 101 A
2 1 101 B
3 2 101 C
4 2 101 D
5 null 100 E
6 5 100 F
How can I do it in T-SQL?
You probably want to use a common table expression which allows you to generate recursive queries.
eg:
;with cte as
(
select * from yourtable where id=1
union all
select t.* from cte
inner join yourtable t on cte.id = t.parentid
)
update yourtable
set userid = 101
where id in (select id from cte)