Reputation: 4478
Say i have a table, values
, which looks like:
id|field_id|value|date
1 |1 |2 |2013-06-01
2 |2 |5 |2013-06-01
3 |1 |3 |2013-06-02
4 |2 |9 |2013-06-02
5 |1 |6 |2013-06-03
6 |2 |4 |2013-06-03
And another table, fields
, which looks like
id|code
1 |small_value
2 |large_value
I would like to select the rows from values
where small_value
is larger than large_value
on the same date
. So for the example above, the query should return the last two rows from since 6
, (field_id
= 1
== small_value
) > 4
(field_id
= 2
== large_value
).
Database is Microsoft SQL Server 2012.
Thanks for any help
Upvotes: 2
Views: 25030
Reputation: 1055
This would do the trick. Note that I have omitted the fields table from the answer, since I don't need to use fields.code for the WHERE conditions, but can use fields.id instead. This is the same as field_id in the values table.
SELECT V.id, V.field_id, V.value, V.date
FROM [values] AS V
INNER JOIN [values] AS V1
ON V.date = V1.date
WHERE (((V.field_id)=1) AND ((V.value)>[V1].[value]) AND ((V1.field_id)=2))
OR (((V.field_id)=2) AND ((V.value)<[V1].[value]) AND ((V1.field_id)=1))
ORDER BY V.id;
Or, if you want all the information in one line:
SELECT V.id, V.field_id, V.value, V1.id, V1.field_id, V1.value, V.date
FROM [values] AS V INNER JOIN [values] AS V1 ON V.date = V1.date
WHERE (((V.field_id)=1) AND ((V.value)>[V1].[value]) AND ((V1.field_id)=2))
ORDER BY V.id;
Upvotes: 0
Reputation:
One way:
select [date],
max(case field_id when 1 then [value] end) small_value,
max(case field_id when 2 then [value] end) large_value
from [values]
group by [date]
having max(case field_id when 1 then [value] end) >
max(case field_id when 2 then [value] end)
SQLFiddle here.
Alternatively, to see the records as separate rows, try:
select v1.*
from [values] v1
join [values] v2
on v1.[date] = v2.[date] and
v1.field_id = 3-v2.field_id and
case v1.field_id when 1 then v1.[value] else v2.[value] end >
case v1.field_id when 2 then v1.[value] else v2.[value] end
SQLFiddle here.
Upvotes: 1
Reputation: 18559
SELECT
small.[Date]
, small.ID as SmallID
, small.Value as SmallValue
, large.ID as LargeID
, large.Value as LargeValue
FROM [values] small
INNER JOIN [values] large ON small.[Date] = large.[Date] AND small.field_id =1 AND large.field_id =2
WHERE small.Value > large.Value
Upvotes: 1
Reputation: 22054
Like this, or I am missing something ? :
declare @tmp table (
id int,
field_id int,
value int,
[date] datetime
)
select * from @tmp
where [date] in (
select distinct t.[date]
from @tmp t
left join (select * from @tmp) as s on s.[Date] = t.[Date]
and s.field_id = 1
left join (select * from @tmp) as l on l.[Date] = t.[Date]
and l.field_id = 2
where s.value > l.value
)
Upvotes: 1
Reputation: 166396
How about something like
SELECT *
FROM [values] v
WHERE EXISTS(
SELECT 1
FROM [values] vl
WHERE vl.FIELD_ID = 2
AND vl.date = v.date
AND vl.value < v.value
)
AND v.FIELD_ID = 1
Here is another possible example
SELECT *
FROM [values] vs INNER JOIN
[values] vl ON vs.date = vl.date AND vs.FIELD_ID = 1 AND vl.FIELD_ID = 2
WHERE vs.value > vl.value
Upvotes: 9