Reputation: 1
I have a query I need for an application I'm building, but I'm struggling to find the best answer.
Suppose I have a table named Messages
, with the following columns:
MessageID, From, To, Text
I want to count all messages between From
and To
such as that if the table looks like this:
ID From To Text
------------------
1 a b hi
2 b a hello
3 a c test
So basically I want the result to look like
a, b, 2
a, c, 1
Appreciate your help
Upvotes: 0
Views: 153
Reputation: 1270873
Most databases have least()
and greatest()
, which make this easier. In SQL Server, you can use case
:
select (case when [from] < [to] then [from] else [to] end),
(case when [from] < [to] then [to] else [from] end),
count(*)
from t
group by (case when [from] < [to] then [from] else [to] end),
(case when [from] < [to] then [to] else [from] end);
I would have named the columns, but I can't think of appropriate names.
Upvotes: 2
Reputation: 522626
Similar answer to Gordon, posted about 20 seconds later, with one important difference. ANSI SQL requires that no derived columns appear in the GROUP BY
clause. I first use a CTE to compute the least and greatest of the to/from pairs, and then do an aggregation query on that CTE. In this case, we end up grouping on actual, not derived, columns.
WITH cte AS (
SELECT
CASE WHEN [From] < [To] THEN [From] ELSE [To] END AS [From],
CASE WHEN [From] >= [To] THEN [From] ELSE [To] END AS [To]
FROM yourTable
)
SELECT
[From], [To], COUNT(*) AS cnt
FROM cte
GROUP BY
[From], [To]
Note also that you should avoid using SQL keywords such as From
to name your columns and tables. To get this query to work, you absolutely would have to use the column as [From]
, because without brackets SQL Server would confound it with the FROM
keyword.
Upvotes: 5