加入两个表并计算结果中的字段

时间:2014-12-15 19:27:15

标签: sql sql-server sql-server-2008 tsql

SQL Server 2008/2012数据库中有2个表。 第一个表是 table1 ,其中字段m1具有汇总值(作为计数器) - 在2014-12-15 13:00:00它具有10000个实际值(80000 - 70000)并且具有因子1, p1 字段已经有因子0.01的实际数据 - 在2014-12-15 13:00:00其值等于10.89(1089 * 0.01),fiel V1有实际数据和因子1:

| DateTime            |   m1  |  p1  |  V1   |
|---------------------|-------|------|-------|
| 2014-12-15 08:00:00 | 45000 | 1045 | 23.45 |
| 2014-12-15 09:00:00 | 51000 | 1078 | 25.78 |
| 2014-12-15 10:00:00 | 58000 | 1056 | 24.99 |    
| 2014-12-15 11:00:00 | 62000 | 1069 | 27.34 |    
| 2014-12-15 12:00:00 | 70000 | 1045 | 29.90 |  
| 2014-12-15 13:00:00 | 80000 | 1089 | 28.67 |

第二个表是 table2 有字段m2具有因子1的实数据,字段p2具有因子0.01的实数据,字段V2具有汇总数据和因子0.1:

| DateTime            |  m2 |  p2  |  V2   |
|---------------------|-----|------|-------|
| 2014-12-15 08:00:00 | 456 | 2045 | 34500 |
| 2014-12-15 09:00:00 | 480 | 2080 | 35600 |
| 2014-12-15 10:00:00 | 495 | 2090 | 35900 |    
| 2014-12-15 11:00:00 | 445 | 2056 | 36700 |    
| 2014-12-15 12:00:00 | 458 | 2076 | 37200 |  
| 2014-12-15 13:00:00 | 478 | 2067 | 38000 |

我会在查询这样的表

的结果
| DateTime            |   m1  |   p1  |  V1   |  m2 |   p2  |  V2   |
|---------------------|-------|-------|-------|-----|-------|-------|
| 2014-12-15 08:00:00 | ----- | 10.45 | 23.45 | 456 | 20.45 | ----- |
| 2014-12-15 09:00:00 | 6000  | 10.78 | 25.78 | 480 | 20.80 |  110  |
| 2014-12-15 10:00:00 | 7000  | 10.56 | 24.99 | 495 | 20.90 |  30   |     
| 2014-12-15 11:00:00 | 4000  | 10.69 | 27.34 | 445 | 20.56 |  80   |    
| 2014-12-15 12:00:00 | 8000  | 10.45 | 29.90 | 458 | 20.76 |  50   |  
| 2014-12-15 13:00:00 | 10000 | 10.89 | 28.67 | 478 | 20.67 |  80   |

使用哪个查询获得此结果?感谢。

2 个答案:

答案 0 :(得分:0)

您可以尝试此示例sql查询。而不是在SQL中使用id列,而是在表中使用DateTime列。显示" ---"在m1和V2列中,您可以在应用程序级别替换。

您可以在此示例查询here找到DEMO。

SELECT Table1.id,Table1.m1,Table1.p1,Table1.V1,
       Table2.m2,Table2.p2,Table2.V2
 FROM (
         SELECT  f.id, 
                (f.m1 - ISNULL(f2.m1,0)) AS m1,
          substring(Convert(varchar(10),(CONVERT(Numeric(6,2),f.p1)/100)),0,6) as p1,
          f.V1
          FROM t1 f LEFT OUTER JOIN t1 f2
          ON  (f2.id+1) = (f.id)
) AS Table1 
INNER JOIN (
            SELECT  f.id, f.m2,     
            substring(Convert(varchar(10),(CONVERT(Numeric(6,2),f.p2)/100)),0,6) as p2,
            (f.V2 - ISNULL(f2.V2,0)) * 0.1 AS V2
            FROM t2 f
            LEFT OUTER JOIN t2 f2
            ON  (f2.id+1) = (f.id)
           ) 
  AS Table2
  ON Table1.id = Table2.id

答案 1 :(得分:0)

一些事情

SELECT
  CONVERT(varchar(30), T1.dateTime, 120)
  , CASE LAG (m1, 1, 0) OVER (ORDER BY m1)
      WHEN 0 THEN '-----'
      ELSE CONVERT(VARCHAR(5), m1 - LAG (m1, 1, 0) OVER (ORDER BY m1)) END AS m1
  , p1 * 0.01 AS p1
  , v1
  , m2
  , p2 * 0.01 AS p2
  , CASE LAG (v2, 1, 0) OVER (ORDER BY v2)
      WHEN 0 THEN '-----'
      ELSE CONVERT(VARCHAR(3), CONVERT(INTEGER, (v2 - LAG (v2, 1, 0) OVER (ORDER BY v2)) * 0.1)) END AS v2
FROM Table1 T1
JOIN Table2 T2
  ON T1.dateTime = T2.dateTime;

应该有效。但不确定,转向" m1"和" v2"进入VARCHAR真的,你需要/想要什么。

SQL Fiddle

抱歉 - 没有注意您的SQL Server版本。遗憾的是,LAG在旧版本中不可用。但有一些解决方法。借用SQL SERVER – Solution to Puzzle – Simulate LEAD() and LAG() without Using SQL Server 2012 Analytic Function来获取

WITH
Sub1 AS (
  SELECT ROW_NUMBER() OVER(ORDER BY T1.dateTime) n,
     T1.dateTime,
     T1.m1,
     T1.p1 * 0.01 AS p1,
     T1.v1,
     T2.m2,
     T2.p2 * 0.01 AS p2,
     T2.v2
  FROM Table1 T1
  JOIN Table2 T2
    ON T1.dateTime = T2.dateTime
),
Sub2 AS (
  SELECT dateTime, m1, p1, v1, m2, p2, v2,
    CASE WHEN n % 2 = 1 THEN MAX(CASE WHEN n % 2 = 0 THEN m1 END) OVER (PARTITION BY n / 2) ELSE MAX(CASE WHEN n % 2 = 1 THEN m1 END) OVER (PARTITION BY (n + 1) / 2) END m1Lag,
    CASE WHEN n % 2 = 1 THEN MAX(CASE WHEN n % 2 = 0 THEN v2 END) OVER (PARTITION BY n / 2) ELSE MAX(CASE WHEN n % 2 = 1 THEN v2 END) OVER (PARTITION BY (n + 1) / 2) END v2Lag
  FROM Sub1
)
SELECT
  CONVERT(varchar(30), dateTime, 120) dateTime
  , CASE m1Lag
      WHEN 0 THEN '-----'
      ELSE CONVERT(VARCHAR(5), m1 - m1Lag) END AS m1
  , p1
  , v1
  , m2
  , p2
  , CASE v2Lag
      WHEN 0 THEN '-----'
      ELSE CONVERT(VARCHAR(3), CONVERT(INTEGER, (v2 - v2Lag) * 0.1)) END AS v2
FROM Sub2
ORDER BY dateTime;

更新了SQL Fiddle