Reputation: 4169
I would like to find all records in Column A where, after sorting Column C in ascending order, Column D begins with a value other than the earliest date.
From the below example, I would want it to return records for Ex2 and Ex3 and not return records for Ex1.
REVISED UPDATES/REQUIREMENTS:
1) I would like it grouped by Column A and ordered by Column C.
2) I would like to find all records in Column A where the first value in Column D is not the lowest date.
Column A Column B Column C Column D
-------- -------- -------- --------
Ex1 Title A 1 2003/1/1
Ex1 Title B 2 2003/2/2
Ex2 Title C 3 2004/4/4
Ex2 Title D 4 2004/3/3
Ex3 Title E 5 2005/6/6
Ex3 Title F 6 2005/5/5
Any Ideas?
Upvotes: 1
Views: 4743
Reputation: 2870
You appear to assume an ordering by [Column B], which you can make explicit in a self join:
SELECT t1.[Column A], t1.[Column B], t1.[Column C], t1.[Column D]
FROM YourTableName t1
JOIN YourTableName t2
ON t2.[Column A] = t1.[Column A]
AND t2.[Column B] > t1.[Column B]
WHERE t2.[Column C] > t1.[Column C]
AND t2.[Column D] < t1.[Column D]
This assumes there are exactly two rows where [Column A] = 'Ex1', etc. If you have more than two rows with the same value in [Column A] you will probably find the results to be unexpected.
Note that the first two comparisons are part of the join condition, and the third and fourth comparisons are part of the WHERE clause.
UPDATE:
Working to changed requirements: There may be twenty rows with [Column A] = 'Ex1'. Return distinct values of [Column A] for which the lowest value of [Column C] is not in the same row as the lowest value of [Column D]. [Column B] is not relevant.
SELECT DISTINCT t1.[Column A]
FROM YourTableName t1
JOIN
(SELECT [Column A], MIN([Column C]) AS MinC, MIN([Column D]) AS MinD
FROM YourTableName
GROUP BY [Column A]) t2
ON t2.[Column A] = t1.[Column A]
WHERE t1.[Column C] = t2.MinC
AND t1.[Column D] <> t2.MinD
This returns:
Column A
Ex1
For the following test table:
CREATE TABLE YourTableName
([Column A] VARCHAR(50),
[Column B] VARCHAR(50),
[Column C] INT,
[Column D] INT)
And test data:
INSERT INTO YourTableName
([Column A], [Column B], [Column C], [Column D])
VALUES ('Ex1', 'Title A', 1, 2)
INSERT INTO YourTableName
([Column A], [Column B], [Column C], [Column D])
VALUES ('Ex1', 'Title B', 2, 1)
INSERT INTO YourTableName
([Column A], [Column B], [Column C], [Column D])
VALUES ('Ex1', 'Title C', 3, 1)
Upvotes: 2
Reputation: 8558
New answer specifically addressing the following specifications (which seem to comprise the problem now):
UPDATE: I would like it grouped by Column A and ordered by Column C.
UPDATE #2: I want to return all examples from Column A where the "first" value in Column D is not the lowest value.
SELECT a.*
FROM tableName a
WHERE a.columnD <> (
SELECT min(columnD)
FROM tableName b
WHERE a.columnA=b.columnA
)
ORDER BY a.columnC
Upvotes: 1
Reputation: 461
select * from table where C =
(select MIN(D) from table)
AND
(select * from table where D = (select MAX(D) from table))
null means false else true
Upvotes: -1
Reputation: 8558
This technique is called a "self join."
SELECT a.*
FROM tableName a, tableName b
WHERE a.column_a = b.column_a
AND a.column_c < b.column_c
AND a.column_d > b.column_d
This assumes that the values in column_a are filled down and there aren't actually nulls as you showed in your example.
Upvotes: 0
Reputation: 18559
Using ranking functions, it can be done something like this:
SELECT * FROM
(
SELECT
*
, ROW_NUMBER() OVER (PARTITION BY ColumnA ORDER BY ColumnC) AS RankC
, ROW_NUMBER() OVER (PARTITION BY ColumnA ORDER BY ColumnD) AS RankD
FROM MyTable
) x
WHERE RankC <> RankD
Upvotes: 0