SQL在where子句中使用子查询并使用select

时间:2018-02-03 22:48:25

标签: sql sql-server

我无法弄清楚如何在我有一个主选择列表的地方完成它,其中我想使用我在where子句中的子查询中选择的值。我的查询也有连接语句..loosely代码看起来像这样

    if object_id('tempdb..#tdata') is not null drop table #tdata;
    go

    create table #tdata(
      machine_id varchar(12),
      temestamp datetime,
      commit_count int,
      amount decimal(6,2)
    );

    if object_id('tempdb..#tsubqry') is not null drop table #tsubqry;
    go
    --Edit:this is just to elaborate question, it will be a query that
    --will return data which I want to use as if it was a temp table
    --based upon condition in where clause..hope makes sense
    create table #tsubqry(
      machine_id varchar(12),
      temestamp datetime,
      amount1 decimal(6,2),
      amount2 decimal(6,2)
    );


    insert into #tdata select 'Machine1','2018-01-02 13:03:18.000',1,3.95;
    insert into #tdata select 'Machine1','2018-01-02 02:11:19.000',1,3.95;
    insert into #tdata select 'Machine1','2018-01-01 23:18:16.000',1,3.95;

    select m1.machine_id, m1.commit_count,m1.amount,***tsub***.amount1,***tsub***.amount2

    from #tdata m1, (select amount1,amount2 from #tsubqry where machine_id=#tdata.machine_id) as ***tsub***
    left join sometable1 m2 on m1.machine_id=m2.machine_id;

编辑:我已经尝试过加入,但是我没有绑定m1.timestamp,因为我需要比较这些日期,这是我的加入声明

from #tdata m1
    left join (
        select amount1,amount2 from #tsubqry where cast(temestamp as date)<=cast(m1.temestamp as date)
    ) tt on m1.machine_id=tt.machine_id

问题是我想使用一些值,这些值必须从另一个符合主查询条件的表中引入,并且最重要的是,来自另一个表的那些值必须位于主查询的列列表中。 希望它有一定道理。 提前致谢

2 个答案:

答案 0 :(得分:1)

这里似乎有几件事情不对,但我想我知道你要去哪里。

我认为你缺少的第一件事是#tsubqry表上的temestamp。由于您以后引用它,我假设它应该在那里。因此,您的表定义需要包含该字段:

create table #tsubqry(
  machine_id varchar(12),
  amount1 decimal(6,2),
  amount2 decimal(6,2),
  temestamp datetime
);

现在,在你的查询中,我认为你试图在你的suquery中使用#tdata中的一些字段......在where子句中很好,但不是from子句。

另外,我认为你不想为每个匹配的#tsubqry复制#tdata的所有数据,所以你可能想要分组。基于这些假设,我认为您的查询需要看起来像这样:

  select m1.machine_id, m1.commit_count, m1.amount, sum(tt.amount1), sum(tt.amount2)
  from #tdata m1
  left join  #tsubqry tt  on m1.machine_id=tt.machine_id
  and cast(tt.temestamp as date)<=cast(m1.temestamp as date)
  group by m1.machine_id, m1.commit_count, m1.amount

答案 1 :(得分:0)

MS SQL Server实际上有一个内置的编程结构,我认为这在这里很有用,作为加入子查询的替代解决方案:

-- # ###
-- # Legends
-- # ###
-- # 
-- # Table Name and PrimaryKey changes (IF machine_id is NOT the primary key in table 2, 
-- # suggest make one and keep machine_ie column as an index column).
-- #
-- #
-- #   #tdata   --> table_A
-- #   #tsubqry --> table_B
-- #

-- =====

-- SOLUTION 1 :: JOIN on Subquery

SELECT 
  m1.machine_id, 
  m1.commit_count, 
  m1.amount, 
  m2.amount1, 
  m2.amount2
FROM table_A m1
INNER JOIN (
    SELECT machine_id, amount1, amount2, time_stamp
    FROM table_B
) AS m2 ON m1.machine_id = m2.machine_id
WHERE m1.machine_id = m2.machine_id
  AND CAST(m2.time_stamp AS DATE) <= CAST(m1.time_stamp AS DATE);

-- SOLUTION 2 :: Use a CTE, which is specific temporary table in MS SQL Server 

WITH table_subqry AS
(
  SELECT machine_id, amount1, amount2, time_stamp
  FROM table_B
)
SELECT 
  m1.machine_id, 
  m1.commit_count, 
  m1.amount, 
  m2.amount1, 
  m2.amount2
FROM table_A m1
LEFT JOIN table_subqry AS m2 ON m1.machine_id = m2.machine_id
WHERE m1.machine_id = m2.machine_id
  AND CAST(m2.time_stamp AS DATE) <= CAST(m1.time_stamp AS DATE);

另外,我创建了一个SQLFiddle,以防它有用。我不知道你的所有数据是什么样的,但至少这个小提琴有你的架构并运行CTE查询而不会出现任何错误。 如果您需要更多帮助,请告诉我们!

SQL Fiddle

Source: Compare Time SQL Server

SQL SERVER Using a CTE

干杯。