How to show all same values from a column in sql? - sql

I have a table Group
group no -of -win
------ ---
a 3
b 3
c 4
How can I show
group
---------
a
b
as output? That is, the set of groups that have the same number of wins.

use self join
DEMO
select distinct a.group from tablename a
join tablename b where a.group<>b.group and a.noofwin=b.noofwin
OUTPUT:
grp
a
b

SELECT GroupName
FROM Groups a
WHERE EXISTS(SELECT TOP 1 1 FROM Groups b WHERE b.GroupName <> a.GroupName AND b.Score = a.Score)

Related

How to select rows by max value from another column in Oracle

I have two datasets in Oracle Table1 and Table2.
When I run this:
SELECT A.ID, B.NUM_X
FROM TABLE1 A
LEFT JOIN TABLE2 B ON A.ID=B.ID
WHERE B.BOOK = 1
It returns this.
ID NUM_X
1 10
1 5
1 9
2 2
2 1
3 20
3 11
What I want are the DISTINCT ID where NUM_X is the MAX value, something like this:
ID NUM_x
1 10
2 2
3 20
You can use aggregation:
SELECT A.ID, MAX(B.NUM_X)
FROM TABLE1 A LEFT JOIN
TABLE2 B
ON A.ID = B.ID
WHERE B.BOOK = 1
GROUP BY A.ID;
If you wanted additional columns, I would recommend window functions:
SELECT A.ID, MAX(B.NUM_X)
FROM TABLE1 A LEFT JOIN
(SELECT B.*,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY NUM_X DESC) as seqnum
FROM TABLE2 B
) B
ON A.ID = B.ID AND B.seqnum = 1
WHERE B.BOOK = 1
GROUP BY A.ID;

SQL query to identify rows not contained contained in another table across multiple subsets

I have two tables as seen below.
Table 1:
Day Group
---------
1 A
1 B
1 C
2 B
2 C
2 D
3 C
3 D
3 E
Table 2:
Group
-------
A
B
C
D
E
I would like to create a SQL query that identifies each Group that exists in Table 2 but does not exist in Table 1 partitioned by Day.
The desired result would look like this:
Day Group
---------
1 D
1 E
2 A
2 E
3 A
3 B
Use a cross join to generate all combinations and then weed out what you have:
select d.day, t1.group
from (select distinct day from table1) d cross join
table2 g left join
table1 t1
on t1.day = d.day and t1.group = g.group
where t1.day is null;
SELECT
*
FROM
(
SELECT DISTINCT
Day
FROM
Table1
) AS Days
,
Table2
WHERE
NOT EXISTS (
SELECT
*
FROM
Table1
WHERE
Table1.day=Days.Day AND
Table1.Group=Table2.Group
)

Count similar values from table by combining two tables

I have two table
table A
name id
ABC 1
PQR 2
XYZ 1
QWE 2
DFG 3
Another table
table B
id idname
1 stuart
2 bob
3 alex
expected output
id idname count
1 stuart 2
2 bob 2
3 alex 1
Iam using oracle 9i, Is it possible to obtain the expected result?
I have tried using distinct keyword but its not helping as it provides only the total count
That's simple. Join and count:
select b.id,
b.idname,
count(*) as cnt
from table_a a
join table_b b on a.id = b.id
group by b.id, b.idname;
If you need all the record from table b even if there is no corresponding row in table a, you can use an outer join:
select b.id,
b.idname,
count(a.id) as cnt
from table_a a
right join table_b b on a.id = b.id
group by b.id, b.idname;
Same can be achieved by using a left join:
select b.id,
b.idname,
count(a.id) as cnt
from table_b b
left join table_a a on a.id = b.id
group by b.id, b.idname;
Use JOIN to get data from both tables and use the aggregate function COUNT with GROUP BY.
Query
select t1.id, t1.idname, count(t2.name) as count
from TableB t1
left join TableA t2
on t1.id = t2.id
group by t1.id, t1.idname
order by count(t2.name) desc, t1.id;;

sql excluding certain results

lets say i have a data set of
A B
-- --
a 1
b 1
c 1
d 1
d 2
e 1
f 1
f 2
g 1
how would i exclude a result in column B of 1, if column B has values of both 1 and 2 for the same value in column A?
i want my results to look like this
A B
-- --
a 1
b 1
c 1
d 2
e 1
f 2
g 1
Checking explicitly here for the values 1 and 2 and using the fact that there are exactly two of them. You could potentially make this less cumbersome if it's safe to assume that you always want the highest value.
select
tbl.A,
tbl.B
from
Table1 tbl
left outer join (
select
A
from
Table1
where
B in (1,2)
group by
A
having
count(B) = 2
) mlt on tbl.A = mlt.A
where
(
mlt.A is not null
and tbl.B = 2
) or (
mlt.A is null
and tbl.B = 1
)
Figure out all the A values that have both 1 and 2.
Match those to the table on the A value.
If A is in the subquery, use the B = 2 record. If it isn't, use the B = 1 record.
select
* from tbl where a IN
(
select
a from tbl
group by a
having count(*)>1
)
and b!=1
UNION ALL
select
* from tbl where a IN
(
select
a from tbl
group by a
having count(*)=1
)
For the example data and desired result, the simplest query to achieve the result would be a GROUP BY operation and an aggregate function.
SELECT d.A
, MAX(d.B) AS B
FROM my_data_set d
GROUP BY d.A
ORDER BY d.A
If we are only interested in rows that have a 1 or 2 in column B, we can add a WHERE clause
SELECT d.A
, MAX(d.B) AS B
FROM my_data_set d
WHERE d.B IN (1,2)
GROUP BY d.A
ORDER BY d.A
With the example data, the output is the same.
Both of these statements achieve the specified result. (There is only a single row returned for each distinct value in A.)
Or, for the same the example data, we can return the same result set with a more literal implementation of the specification.
To exclude rows with 1when there is a row with 2 for the same value of A, we can use a NOT EXISTS predicate and a correlated subquery.
SELECT d.A
, d.B
FROM my_data_set d
WHERE ( d.B = 2 )
OR ( d.B = 1 AND
NOT EXISTS ( SELECT 1
FROM my_data_set e
WHERE e.A = d.A
AND e.B = 2
)
)
ORDER BY d.A, d.B

Postgresql query with left join and having

Postgresql 9.1: I have a query that must return the values of a second table only if the aggregate function SUM of two columns is greater than zero.
This is the data:
Table a
id
---
1
2
3
Table b
id fk(table a)
---------------
1 1
2 null
3 3
Table c
id fk(table b) amount price
-----------------------------------
1 1 1 10 --positive
2 1 1 -10 --negative
3 3 2 5
As you can see, table b has some ids from table a, and table c can have 1 or more references to table b, table c is candidate to be retrieved only if the sum(amount * price ) > 0.
I wrote this query:
SELECT
a.id, b.id, SUM(c.amount * c.price) amount
FROM
tablea a
LEFT JOIN
tableb b ON b.fk = a.id
LEFT JOIN
tablec c ON c.fk = b.id
GROUP BY
a.id, b.id
HAVING
SUM(c.amount * c.price) > 0
But this query is not retrieving all rows from table a just the row 1 and I need the two rows. I understand this is happening because of the HAVING clause but I don't know how to rewrite it.
Expected result
a b sum
------------------
1 null null -- the sum of 1 * 10 (rows 1 and two) = 0 so its not retrieved.
2 null null -- no foreign key in second table
3 3 10 -- the sum of 2 * 5 (row 3) > 0 so it's ok.
Try this:
SELECT A.ID, B.ID, C.ResultSum
FROM TableA A
LEFT JOIN TableB B ON (B.FK = A.ID)
LEFT JOIN (
SELECT FK, SUM(Amount * Price) AS ResultSum
FROM TableC
GROUP BY FK
) C ON (C.FK = B.ID) AND (ResultSum > 0)
See demo here.