SQL query for joining two columns into one - sql

I have a table of matches and scores, which looks something like this
match_id | player1 | player2 | player1_score | player2_score |
---------|---------|---------|---------------|---------------|
1 | 1 | 2 | 30 | 50 |
2 | 3 | 1 | 35 | 10 |
3 | 1 | 4 | 40 | 20 |
4 | 2 | 3 | 20 | 25 |
5 | 4 | 2 | 65 | 15 |
6 | 3 | 4 | 10 | 20 |
and I want to make a query with the scores in a single column
match_id | player | opponent | score |
---------|--------|----------|-------|
1 | 1 | 2 | 30 |
2 | 3 | 1 | 35 |
3 | 1 | 4 | 40 |
4 | 2 | 3 | 20 |
5 | 4 | 2 | 65 |
6 | 3 | 4 | 10 |
1 | 2 | 1 | 50 |
2 | 1 | 3 | 10 |
3 | 4 | 1 | 20 |
4 | 3 | 2 | 25 |
5 | 2 | 4 | 15 |
6 | 4 | 3 | 20 |
This would be equivalent to concatenating some columns in the table with others:
match_id | player | opponent | score |
---------|---------|----------|---------------|
match_id | player1 | player2 | player1_score |
match_id | player2 | player1 | player2_score |
but I'm not not sure what the appropriate operation would be. join is the only operation I know that combines tables, but it seems like the wrong tool here.
Either CONCAT or UNION seems reasonable, but which would be preferable here? And what would the query be?

seems you need an union
select match_id, player1, player2 opponent, player1_score score
from my_table
union all
select match_id, player1, player2 , player2_score
from my_table

Related

sql (oracle) counting number of overlapping intervals

I have the following problem:
Given the following table test in an oracle sql database:
+----+------+-------+------+
| id | name | start | stop |
+----+------+-------+------+
| 1 | A | 1 | 5 |
+----+------+-------+------+
| 2 | A | 2 | 6 |
+----+------+-------+------+
| 3 | A | 5 | 8 |
+----+------+-------+------+
| 4 | A | 9 | 10 |
+----+------+-------+------+
| 5 | B | 3 | 6 |
+----+------+-------+------+
| 6 | B | 4 | 8 |
+----+------+-------+------+
| 7 | B | 1 | 2 |
+----+------+-------+------+
I would like to find the number of overlapping intervals (endpoints included) [start, stop] n_overlap, for all id having the same name, i.e.:
+----+------+-------+------+-----------+
| id | name | start | stop | n_overlap |
+----+------+-------+------+-----------+
| 1 | A | 1 | 5 | 3 |
+----+------+-------+------+-----------+
| 2 | A | 2 | 6 | 3 |
+----+------+-------+------+-----------+
| 3 | A | 4 | 8 | 3 |
+----+------+-------+------+-----------+
| 4 | A | 9 | 10 | 1 |
+----+------+-------+------+-----------+
| 5 | B | 3 | 6 | 2 |
+----+------+-------+------+-----------+
| 6 | B | 4 | 8 | 2 |
+----+------+-------+------+-----------+
| 7 | B | 1 | 2 | 1 |
+----+------+-------+------+-----------+
One method uses a correlated subquery:
select t.*,
(select count(*)
from test t2
where t2.name = t.name and
t2.start < t.end and
t2.end > t.start
) as num_overlaps
from test t;

writing SQL query to show result in specific order

I have this table
+----+--------+------------+-----------+
| Id | day_id | subject_id | period_Id |
+----+--------+------------+-----------+
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 2 |
| 8 | 2 | 6 | 1 |
| 9 | 2 | 7 | 2 |
| 15 | 3 | 3 | 1 |
| 16 | 3 | 4 | 2 |
| 22 | 4 | 5 | 1 |
| 23 | 4 | 5 | 2 |
| 24 | 4 | 6 | 3 |
| 29 | 5 | 8 | 1 |
| 30 | 5 | 1 | 2 |
to something like this
| Id | day_id | subject_id | period_Id |
| 1 | 1 | 1 | 1 |
| 8 | 2 | 6 | 1 |
| 15 | 3 | 3 | 1 |
| 22 | 4 | 5 | 1 |
| 29 | 5 | 8 | 1 |
| 2 | 1 | 2 | 2 |
| 2 | 1 | 2 | 2 |
| 16 | 3 | 4 | 2 |
| 23 | 4 | 5 | 2 |
| 30 | 5 | 1 | 2 |
+----+--------+------------+-----------+
SO, I want to choose one period with a different subject each day and doing this for number of weeks. so first subject dose not come until all subject have been chosen.
You can ORDER BY period_id first and then by day_id:
SELECT *
FROM your_table
ORDER BY period_Id, day_Id
LiveDemo

SQL Select and Group By clause

I have data as per the table below, I pass in a list of numbers and need the raceId where all the numbers appear in the the data column for that race.
+-----+--------+------+
| Id | raceId | data |
+-----+--------+------+
| 14 | 1 | 1 |
| 12 | 1 | 2 |
| 13 | 1 | 3 |
| 16 | 1 | 8 |
| 47 | 2 | 1 |
| 43 | 2 | 2 |
| 46 | 2 | 6 |
| 40 | 2 | 7 |
| 42 | 2 | 8 |
| 68 | 3 | 3 |
| 69 | 3 | 6 |
| 65 | 3 | 7 |
| 90 | 4 | 1 |
| 89 | 4 | 2 |
| 95 | 4 | 6 |
| 92 | 4 | 7 |
| 93 | 4 | 8 |
| 114 | 5 | 1 |
| 116 | 5 | 2 |
| 117 | 5 | 3 |
| 118 | 5 | 8 |
| 138 | 6 | 2 |
| 139 | 6 | 6 |
| 140 | 6 | 7 |
| 137 | 6 | 8 |
+-----+--------+------+
Example I pass in 1,2,7 I would get the following Id's:
2 and 4
I have tried the simple statement
SELECT * FROM table WHERE ((data = 1) or (data = 2) or (data = 7))
But I don't really understand the grouping by clause or indeed if it is the correct way of doing this.
select raceId
from yourtable
where data in (1,2,7)
group by raceId
having count(raceId) = 3 /* length(1,2,7) */
This is assuming raceId, data pair is unique. If it's not the you should use
select raceId
from (select distinct raceId, data
from yourtable
where data in(1,2,7))
group by raceId
having count(raceId) = 3
SELECT DISTINCT raceId WHERE data IN (1, 2, 7)
This is an example of a "set-within-sets" query. I like to solve these with group by and having.
select raceid
from races
where data in (1, 2, 7)
group by raceid
having count(*) = 3;

How to generate merit list from exam results in SQL Server

I'm using SQL Server 2008 R2. I have a table called tstResult in my database.
AI SubID StudID StudName TotalMarks ObtainedMarks
--------------------------------------------------------
1 | 1 | 1 | Jakir | 100 | 90
2 | 1 | 2 | Rubel | 100 | 75
3 | 1 | 3 | Ruhul | 100 | 82
4 | 1 | 4 | Beauty | 100 | 82
5 | 1 | 5 | Bulbul | 100 | 96
6 | 1 | 6 | Ripon | 100 | 82
7 | 1 | 7 | Aador | 100 | 76
8 | 1 | 8 | Jibon | 100 | 80
9 | 1 | 9 | Rahaat | 100 | 82
Now I want a SELECT query that generate a merit list according to the Obtained Marks. In this query obtained marks "96" will be the top in the merit list and all the "82" marks will be placed one after another in the merit list. Something like this:
StudID StudName TotalMarks ObtainedMarks Merit List
----------------------------------------------------------
| 5 | Bulbul | 100 | 96 | 1
| 1 | Jakir | 100 | 90 | 2
| 9 | Rahaat | 100 | 82 | 3
| 3 | Ruhul | 100 | 82 | 3
| 4 | Beauty | 100 | 82 | 3
| 6 | Ripon | 100 | 82 | 3
| 8 | Jibon | 100 | 80 | 4
| 7 | Aador | 100 | 76 | 5
| 2 | Rubel | 100 | 75 | 6
;with cte as
(
select *, dense_rank() over (order by ObtainedMarks desc) as Merit_List
from tstResult
)
select * from cte order by Merit_List desc
you need to use Dense_rank()
select columns from tstResult order by ObtainedMarks desc

Ask about query in sql server

i have table like this:
| ID | id_number | a | b |
| 1 | 1 | 0 | 215 |
| 2 | 2 | 28 | 8952 |
| 3 | 3 | 10 | 2000 |
| 4 | 1 | 0 | 215 |
| 5 | 1 | 0 |10000 |
| 6 | 3 | 10 | 5000 |
| 7 | 2 | 3 |90933 |
I want to sum a*b where id_number is same, what the query to get all value for every id_number? for example the result is like this :
| ID | id_number | result |
| 1 | 1 | 0 |
| 2 | 2 | 523455 |
| 3 | 3 | 70000 |
This is a simple aggregation query:
select id_number, sum(a*b)
from t
group by id_number
I'm not sure what the first column is for.