简体   繁体   中英

SQL - Select rows where one column is greater than other column on the same date

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

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

SQL Fiddle DEMO

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

SQL Fiddle DEMO

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 .

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
    )
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

SQLFiddle Demo

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM