Counting relations between two columns in SQL server - sql

Good morning, I have two columns in sql studio and I need to count the relations between the elements one column and the other one. The problem is it seems only is counting in 'one direction' and I want to know both. Maybe it is easier if I show you in a simple example. I am using SQL server.
This is the original table:
Col1 Col2
3 1
3 2
3 2
4 4
4 5
4 6
3 2
2 3
2 3
And if I do the following (based on count(concat)), it gives the following results.
select Col1, Col2, count(concat(Col1, Col2)) as weight
FROM test1
group by Col1, Col2
Col1 Col2 weight
3 1 1
3 2 3
2 3 2
4 4 1
4 5 1
4 6 1
But what I would like is also counts the relations between the two elements, independently if this is in one column or other. So, the number of relations between 3-2 (or 2-3) would be 5. It is possible to do that?
3 2 5
Any suggestion would be very welcome! Thanks in advance!

Most databases support least() and greatest(). This allows you to do:
select least(col1, col2) as col1, greatest(col1, col2) as col2,
count(*) as cnt
from t
group by least(col1, col2), greatest(col1, col2);
If your database does not support these handy functions, then you can implement similar logic using case expressions.

Related

Finding combinations of specific values

I don't know how to write the query for below.
My table is
col1 col2
5 1
5 5
5 6
5 7
4 5
4 8
4 9
4 3
3 3
3 5
I need to select distinct col1 id where both parameters exists in col2.
eg. if i send 6,7 it should send me 5
This is probably among the fastest solutions:
SELECT col1 -- already DISTINCT?
FROM tbl t1
JOIN tbl t2 USING (col1)
WHERE t1.col2 = 6
AND t2.col2 = 7;
Assuming a PRIMARY KEY or UNIQUE constraint on (col1, col2), like it's typically implemented. Else add DISTINCT.
There are many other ways to implement relational division. Here are some:
How to filter SQL results in a has-many-through relation
Try:
SELECT col1
FROM mytable
WHERE col2 IN (6, 7)
GROUP BY col1
HAVING COUNT(DISTINCT col2) = 2

Renumbering the records in Oracle and SQL Server

I have a table t with following values in col1 -
1
1
3
4
4
4
5
7
10
13
I need to renumber it as following, so it will erase the gaps between numbers.
1
1
2
3
3
3
4
5
6
7
I am able to find the gap ranges. Didn't find the way to renumber - tried to apply analytical function with row_num() but cannot get correct result. Code should work in both Oracle and SQL Server, so connect by level is probably not the best way.
That look like a DENSE_RANK, SQL-Server:
WITH CTE AS
(
SELECT Col1, RANK = DENSE_RANK() OVER (ORDER BY Col1 ASC)
FROM dbo.Table1
)
UPDATE CTE SET Col1 = RANK
WHERE Col1 <> RANK
I'm not familiar with Oracle (anymore) but there's also a Dense_Rank function.
Demo
COL1
1
1
2
3
3
3
4
5
6
7

SQL query to print mirror labels

I want to print labels in words as returned by a SQL query such as follow.
1 2 3
4 5 6
When I want to print the reverse of those labels, I have to print them as follow
3 2 1
6 5 4
In my real case, I have 5 colums by 2 rows, how can I formulate my query so that my records are ordered like the second one.
The normal ordering is handled by word, so my query is like
SELECT * FROM Products ORDER BY Products.id
I'm using MS Access =(
EDIT :
Just to make it clear
I'd like my records to be ordered such as
3 2 1 6 5 4 9 8 7 12 11 10
EDIT2 :
my table looks like this
ID ProductName
1 Product1
2 Product2
3 Product3
n Product[n]
I want the ids to be returned as I mentioned above
SELECT * FROM Products ORDER BY Products.id desc
Alternately if your query at the moment is really giving you this:
select col1, col2, col3 from products order by products.id;
why not use
select col3, col2, col1 from products order by products.id;

Using ROLLUP in query... Small question

It is a "table_one" in oracle database:
COL1 COL2
-----------------
2 4
2 1
13 14
13 15
I have this query:
SELECT col1, sum(col2) FROM table_one GROUP BY ROLLUP(col1, col2);
After query execute I have:
------------
2 1
2 4
2 5
13 14
13 15
13 29
34
but i need in another way, like this:
------------
2 1
2 4
2 5
13 14
13 15
13 29
without summary of all columns
How I can change my query..... ?
There are two ways to solve this problem. The first is to use grouping sets to define exactly what summary groups you want created.
In this case, you can define to group on (col1) and (col1, col2) usig the following query:
select col1, sum(col2)
from table_one
group by grouping sets ((col1), (col1, col2))
Otherwise, you can group by col1 and rollup on col2 using the following query:
select col1, sum(col2)
from table_one
group by col1, rollup(col2)
Both of these queries should produce the output you require.
Use your current query as a sub query. In the outer query, use a WHERE clause that eliminates the NULL value in Col1
SELECT *
FROM
(
-- Your Rollup Query goes here.
SELECT * FROM MyTable
)
WHERE COL1 IS NOT NULL
A better solution was presented in the comments to eliminate NULL values in the source column(s)
Use the GROUPING function to determine if it is a a sub-total.
http://www.remote-dba.net/pl_sql/t_sql_grouping.htm

Multiple row Sums into a Total Column

I have a temp table populated in a sproc that is similar to this:
Company Col1 Col2 Col3 Total
Company1 4 3 2 9
Company2 1 0 3 4
Total ? ? ? ?
Is there a slick way to get the bottom total column populated with SUM of each row in one shot without having to do each column individually using sub-queries?
select sum(col1), sum(col2), sum(col3), sum(col1+col2+col3)
FROM CompanyTable
If the DBMS you use is MS SQL than be aware of how to reference the temporary table:
SELECT SUM(Col1) as TotalOfCol1,...
FROM #Company
If you are using MySQL, you can get the whole table in one query using the WITH ROLLUP feature:
SELECT Company, SUM(Col1), SUM(Col2), SUM(Col3), SUM(Col1 + Col2 + Col3)
FROM Table1
GROUP BY Company
WITH ROLLUP
Results:
'Company1' 4 3 2 9
'Company2' 1 0 3 4
'' 5 3 5 13 <--- This extra row is the column totals