Calculating statistics of interactions between football players - sql-server

I have a table of kicks between a number of football players. Most interactions have both a kicker and receiver, but sometimes the pass is made but never received. The table contains 3 columns. For purposes of the example, I have added a "PassID" column to assist with the description of the problem.
The table looks as follows:
create table #T (Player1 varchar(25),Action varchar(25),Player2 varchar(25),PassID int)
insert into #T select 'Jamie','Kicked to','Pierre',1
insert into #T select 'Pierre','Received from ','Jamie',1
insert into #T select 'Jamie','Kicked to ','Mohamed',2
insert into #T select 'Jamie','Received from ','Kun',3
insert into #T select 'Kun ','Kicked to','Jamie',3
insert into #T select 'Mohamed','Received from ','Pierre',4
insert into #T select 'Pierre','Kicked to','Mohamed',4
insert into #T select 'Mohamed','Kicked to','Kun',5
insert into #T select 'Jamie ','Kicked to ','Kun',6
insert into #T select 'Kun ','Received from ','Jamie',6
insert into #T select 'Jamie','Received from ','Kun',7
insert into #T select 'Kun ','Kicked to','Jamie',7
I have to answer the following question using SQL server:
How many unique interactions exist, where a unique interaction is defined as a kick between two players, whether completed or not and where the direction of the interaction does not matter?
In this simple example, I know the answer is 5,being:
Jamie/Pierre
Jamie/Mohamed
Jamie/Kun
Mohamed/Pierre
Mohamed/Kun
How do I extract this answer from the table using T-SQL statement?

SELECT COUNT(DISTINCT CASE
WHEN Player1 > Player2 THEN CONCAT(Player1,'+',Player2)
ELSE CONCAT(Player2,'+',Player1)
END )
FROM #T
WHERE Action = 'Kicked To';
Here is a SQL Fiddle

Try with the below code.
Select CONCAT(x.Player1,'/',x.Player2)Title from (
Select *,ROW_NUMBER() over (PARTITION by passid order by passid)Row from #T
)X
where Row=1

Related

Display few specific rows always at the top

I want to display a few specific Rows always at top of the query results.
For example: Cities Table. Columns: City ID, City Name
I want to fetch Query result where Mumbai, Bangalore, Chennai, Hyderabad should display at the top always.
1st way:
I can insert these records first in the table so that they will get displayed always at the top.
But, this way will not work if any other city gets added after a few months that I also want to display at the top.
Use an iif in your order by clause:
SELECT CityId, CityName
FROM Cities
ORDER BY IIF(CityName IN ('Mumbai', 'Bangalore', 'Chennai', 'Hyderabad'), 0, 1), CityName
You can't rely on the order in which you've entered the records to the table, because database tables are unsorted by nature, and without an order by clause, the order of the result set will be arbitrary.
For more information, read The “Natural order” misconception on my blog.
Try this:
Declare #t table (cityID int,cityname nvarchar(50))
insert into #t values (2,'Gujrat')
insert into #t values (4,'Surat')
insert into #t values (6,'Mumbai')
insert into #t values (3,'Bangalore')
insert into #t values (5,'Chennai')
insert into #t values (1,'Hyderabad')
select * from #t
order by case when cityname in ('Mumbai','Bangalore','Chennai','Hyderabad') then 0 else 1 END
Clean way of doing this,
Declare #t table (cityID int,cityname nvarchar(50))
Declare #DesireOrder table (id int identity,CityID int) -- instead of cityname
insert into #DesireOrder values (6),(3),(5),(1)
insert into #t values (2,'Gujrat')
insert into #t values (4,'Surat')
insert into #t values (6,'Mumbai')
insert into #t values (3,'Bangalore')
insert into #t values (5,'Chennai')
insert into #t values (1,'Hyderabad')
insert into #t values (8,'Delhi')
insert into #t values (7,'New Delhi')
select t.* from #t t
left join DesireOrder O on t.cityid=O.cityid
order by o.id,t.cityID
Main idea is #DesireOrder, rest you can implement as per your requirement.

Filling the ID column of a table NOT using a cursor

Tables have been created and used without and ID column, but ID column is now needed. (classic)
I heard everything could be done without cursors. I just need every row to contain a different int value so I was looking for some kind of row number function :
How do I use ROW_NUMBER()?
I can't tell exactly how to use it even with these exemples.
UPDATE [TableA]
SET [id] = (select ROW_NUMBER() over (order by id) from [TableA])
Subquery returned more than 1 value.
So... yes of course it return more than one value. Then how to mix both update and row number to get that column filled ?
PS. I don't need a precise order, just unique values. I also wonder if ROW_NUMBER() is appropriate in this situation...
You can use a CTE for the update
Example
Declare #TableA table (ID int,SomeCol varchar(50))
Insert Into #TableA values
(null,'Dog')
,(null,'Cat')
,(null,'Monkey')
;with cte as (
Select *
,RN = Row_Number() over(Order by (Select null))
From #TableA
)
Update cte set ID=RN
Select * from #TableA
Updated Table
ID SomeCol
1 Dog
2 Cat
3 Monkey
You can use a subquery too as
Declare #TableA table (ID int,SomeCol varchar(50))
Insert Into #TableA values
(null,'Dog')
,(null,'Cat')
,(null,'Monkey');
UPDATE T1
SET T1.ID = T2.RN
FROM #TableA T1 JOIN
(
SELECT ROW_NUMBER()OVER(ORDER BY (SELECT 1)) RN,
*
FROM #TableA
) T2
ON T1.SomeCol = T2.SomeCol;
Select * from #TableA

How To Set Limit Table Row SQL?

How to set limit table row in SQL Server?
I want to set limit of my table rows to 100 rows only.
So when the table have more than 100 rows, I want to delete first row then add new row to last row (100).
How can I do this?
One thing that i can assure you..
Create a trigger that if > 100 then delete first record record.
see here as your guide.
I think you hv to do two things
i) Create Trigger
declare #MaxRowLimit int=5
declare #t table(col1 int)
insert into #t values(1),(2),(3),(4),(5)
insert into #t VALUES(12)
;With CTE as
(
select top (#MaxRowLimit) col1
from #t t1
order by t1.col1 desc
)
,CTE1 as(
select * from #t t
where not exists
(select col1
from cte t1 where t.col1=t1.col1
)
)
delete from cte1
select * from #t
ii) If it is bulk insert then,you hv to do manipulation before bulk insert.
like if bulk insert count is greater than 100 then sort and keep last 100 rows and remove rest rows.

how to remove duplicate rows from a table in SQL Server [duplicate]

This question already has answers here:
How can I remove duplicate rows?
(43 answers)
Closed 9 years ago.
I have a table called table1 which has duplicate values. It looks like this:
new
pen
book
pen
like
book
book
pen
but I want to remove the duplicated rows from that table and insert them into another table called table2.
table2 should look like this:
new
pen
book
like
How can I do this in SQL Server?
Let's assume the field was named name:
INSERT INTO table2 (name)
SELECT name FROM table1 GROUP BY name
that query would get you all the unique names.
You could even put them into a table variable if you wanted:
DECLARE #Table2 TABLE (name VARCHAR(50))
INSERT INTO #Table2 (name)
SELECT name FROM table1 GROUP BY name
or you could use a temp table:
CREATE TABLE #Table2 (name VARCHAR(50))
INSERT INTO #Table2 (name)
SELECT name FROM table1 GROUP BY name
You can do this easily with a INSERT that SELECTs from a CTE where you use ROW_NUMBER(), like:
DECLARE #YourTable table (YourColumn varchar(10))
DECLARE #YourTable2 table (YourColumn varchar(10))
INSERT INTO #YourTable VALUES ('new')
INSERT INTO #YourTable VALUES ('pen')
INSERT INTO #YourTable VALUES ('book')
INSERT INTO #YourTable VALUES ('pen')
INSERT INTO #YourTable VALUES ('like')
INSERT INTO #YourTable VALUES ('book')
INSERT INTO #YourTable VALUES ('book')
INSERT INTO #YourTable VALUES ('pen')
;WITH OrderedResults AS
(
SELECT
YourColumn, ROW_NUMBER() OVER (PARTITION BY YourColumn ORDER BY YourColumn) AS RowNumber
FROM #YourTable
)
INSERT INTO #YourTable2
(YourColumn)
SELECT YourColumn FROM OrderedResults
WHERE RowNumber=1
SELECT * FROM #YourTable2
OUTPUT:
YourColumn
----------
book
like
new
pen
(4 row(s) affected)
You can do this easily with a DELETE on a CTE where you use ROW_NUMBER(), like:
--this will just remove them from your original table
DECLARE #YourTable table (YourColumn varchar(10))
INSERT INTO #YourTable VALUES ('new')
INSERT INTO #YourTable VALUES ('pen')
INSERT INTO #YourTable VALUES ('book')
INSERT INTO #YourTable VALUES ('pen')
INSERT INTO #YourTable VALUES ('like')
INSERT INTO #YourTable VALUES ('book')
INSERT INTO #YourTable VALUES ('book')
INSERT INTO #YourTable VALUES ('pen')
;WITH OrderedResults AS
(
SELECT
YourColumn, ROW_NUMBER() OVER (PARTITION BY YourColumn ORDER BY YourColumn) AS RowNumber
FROM #YourTable
)
DELETE OrderedResults
WHERE RowNumber!=1
SELECT * FROM #YourTable
OUTPUT:
YourColumn
----------
new
pen
book
like
(4 row(s) affected)
I posted something on deleting duplicates a couple of weeks ago by using DELETE TOP X. Only for a single set of duplicates obviously. However in the comments I was given this little jewel by Joshua Patchak.
;WITH cte(rowNumber) AS
(SELECT ROW_NUMBER() OVER (PARTITION BY [List of Natural Key Fields]
ORDER BY [List of Order By Fields])
FROM dbo.TableName)
DELETE FROM cte WHERE rowNumber>1
This will get rid of all of the duplicates in the table.
Here is the original post if you want to read the discussion. Duplicate rows in a table.

SQL Server Another simple question

I have 2 temp Tables [Description] and [Institution], I want to have these two in one table.
They are both tables that look like this:
Table1; #T1
|Description|
blabla
blahblah
blagblag
Table2; #T2
|Institution|
Inst1
Inst2
Inst3
I want to get it like this:
Table3; #T3
|Description| |Institution|
blabla Inst1
blahblah Inst2
blagblag Inst3
They are already in sort order.
I just need to get them next to each other..
Last time I asked was something almost the same.
I used this query
Create Table #T3
(
[From] Datetime
,[To] Datetime
)
INSERT INTO #T3
SELECT #T1.[From]
, MIN(#T2.[To])
FROM #T1
JOIN #T2 ON #T1.[From] < #T2.[To]
GROUP BY #T1.[From]
Select * from #T3
It did work for the date values, but it won't work here ? :s
Thank you.
One thing that concerns me is that you say that the values "are already in sort order". There really is no default sort order -- if you don't specify a sort order, you are at the mercy of SQL Server to determine the order in which the data is returned. The solution below assumes that there is some way to sort the data such that the records "match up" (using the ORDER BY clauses).
Hope this helps,
John
-- Table 1 test data
Create Table #T1
(
[Description] nvarchar(30)
)
INSERT INTO #T1 ([Description]) VALUES ('desc1')
INSERT INTO #T1 ([Description]) VALUES ('desc2')
INSERT INTO #T1 ([Description]) VALUES ('desc3')
-- Table 2 test data
Create Table #T2
(
[Institution] nvarchar(30)
)
INSERT INTO #T2 (Institution) VALUES ('Inst1')
INSERT INTO #T2 (Institution) VALUES ('Inst2')
INSERT INTO #T2 (Institution) VALUES ('Inst3')
-- Create table 3
Create Table #T3
(
[Description] nvarchar(30),
[Institution] nvarchar(30)
);
-- Use CTE2 to add row numbers to the data; use the row numbers to join the tables
-- you must specify the sort order for the data in the tables
WITH CTE1 (Description, RowNum) AS
(
SELECT [Description], ROW_NUMBER() OVER(ORDER BY [Description]) as RowNum
FROM #T1
),
CTE2 (Institution, RowNum) AS
(
SELECT Institution, ROW_NUMBER() OVER(ORDER BY Institution) as RowNum
FROM #T2
)
INSERT INTO #T3
SELECT CTE1.Description, CTE2.Institution
FROM CTE1
LEFT JOIN CTE2 ON CTE1.RowNum = CTE2.RowNum
Select * from #T3

Resources