无法按列排序,而在分组依据中不包括列名

问题描述 投票:0回答:1

我无法在分组依据中不包括列名的情况下通过查询进行排序。尝试使用下一个最新的非空值更新最新记录。但是,当我更新记录时,将考虑随机而不是非空值,而不是下一个最新的非空值,因为除非包含在group by中,否则不能执行order by。

表A

  ID     Name   zip  city  Mdate
  10001  Sarah  NULL NULL  02-20-2018 00:10:40:000
  98765  AJ     NULL Asia  03-25-2018 10:10:45:000
  12345  NULL   7511 Texas 03-20-2018 22:10:00:000

表B

  ID     RollNo     Cdate
  12345   1    01-18-2018
  12345   2    01-22-2018
  12345   3    03-20-2018 
  98765   9    01-18-2018
  98765   8    01-22-2018
  98765   7    03-20-2018
  10001   10   03-08-2018 
  10001   11   01-15-2018
  10001   12   02-20-2018

表C

  Rollno Name  Zip  City  Mdate
    1    NULL  7511 Texas 01-18-2018 15:10:00:000 
    2    John  5001 NULL 01-22-2018 10:05:00:000
    3    NULL  7000 Rome 03-20-2018 22:10:00:000
    10   Sarah NULL NULL 03-08-2018 01:00:20:000
    11   Tom   5500 NULL 01-15-2018 15:10:00:000
    12   NULL  4500 Pune 02-20-2018 00:10:40:000
    9    AJ    NULL Asia 01-18-2018 23:01:02:000
    8    MATT  NULL Ohio 01-22-2018 20:00:05:000
    7    NULL  8000 NULL 03-25-2018 10:10:45:000 

查询:

    Update #temp SET Name = C.name
    Zip = C.ZIP
    ,City=C.city

   FROM
   (
   SELECT A.ID,
   CASE 
   WHEN MAX(A.Name) IS NULL THEN MAX(C.Name) 
   ELSE Max(A.Name) 
   END Name,
   CASE
   WHEN MAX(A.Zip) IS NULL THEN Max(C.Zip)
   ELSE MAX(A.Zip)
   END Zip,
   CASE 
   WHEN MAX(A.City) IS NULL THEN Max(C.City) 
   ELSE MAX(A.City) 
   END City,
   A.Mdate
   FROM table_a A
   INNER JOIN Table_B B ON A.ID = B.ID
   INNER JOIN table_c C ON B.RollNo = C.RollNo
   GROUP BY A.ID,A.Mdate
   )

结果集:

   ID     Name   zip  city  Mdate
  10001  Sarah  5500 Pune  03-08-2018 01:00:20:000
  98765  AJ     8000 Asia  03-25-2018 10:10:45:000 
  12345  John   7511 Rome  03-20-2018 22:10:00:000 

实际输出:

   ID     Name   zip  city  Mdate
  10001  Sarah  4500 Pune  03-08-2018 01:00:20:000
  98765  MATT   8000 ohio  03-25-2018 10:10:45:000 
  12345  John   7000 Rome  03-20-2018 22:10:00:000 

如果最新记录包含空值,则应更新下一个最新的非空值记录。在查询中无法为表C提供日期。我已将最新值放入临时表,并仅对特定列执行更新。

sql sql-server tsql
1个回答
0
投票

这是在子查询中进行排序的方式,这不会产生您要查找的结果集(您的原始查询也不会从所提供的数据集中产生实际的输出),但这是方法我会用它来解决问题。

create table #temp (id int, name char(5), zip char(5), city char(5));

       declare @table_a table (id int, name char(5), city char(5), zip char(5), mdate datetime);

       insert @table_a
       values(10001,  'Sarah',  NULL, NULL,  '02-20-2018 00:10:40:000'),
       (98765,  'AJ',     NULL, 'Asia',  '03-25-2018 10:10:45:000'),
       (12345,  NULL,   7511, 'Texas', '03-20-2018 22:10:00:000');

       declare @table_b table (id int, rollno int, Cdate datetime);

       insert @table_b ( ID,     RollNo,     Cdate)
       values
  (12345,   1,    '01-18-2018'),
  (12345,   2,    '01-22-2018'),
  (12345,   3,    '03-20-2018'),
  (98765,   9,    '01-18-2018'),
  (98765,   8,    '01-22-2018'),
  (98765,   7,    '03-20-2018'),
  (10001,   10,   '03-08-2018'), 
  (10001,   11,   '01-15-2018'),
  (10001,   12,   '02-20-2018');

       declare @table_c table ( rollno int, name char(5), city char(5), zip char(5),mdate datetime);

       insert @table_c(  Rollno, Name,  Zip,  City,  Mdate)
       values
    (1,    NULL,  7511, 'Texas', '01-18-2018 15:10:00:000'), 
    (2,    'John',  5001, NULL, '01-22-2018 10:05:00:000'),
    (3,    NULL,  7000, 'Rome', '03-20-2018 22:10:00:000'),
    (10,   'Sarah', NULL, NULL, '03-08-2018 01:00:20:000'),
    (11,   'Tom',   5500, NULL, '01-15-2018 15:10:00:000'),
    (12,   NULL,  4500, 'Pune', '02-20-2018 00:10:40:000'),
    (9,    'AJ',    NULL, 'Asia', '01-18-2018 23:01:02:000'),
    (8,    'MATT',  NULL, 'Ohio', '01-22-2018 20:00:05:000'),
    (7,    NULL,  8000, NULL, '03-25-2018 10:10:45:000');

       declare @count int = coalesce((select count(*) from #temp), 100);

    --Update t SET t.Name = C.name,
    --t.Zip = C.ZIP,
    --t.City=C.city

select * 
   FROM
   (
   SELECT top (@count) A.ID,
   CASE 
   WHEN MAX(A.Name) IS NULL THEN MAX(C.Name) 
   ELSE Max(A.Name) 
   END Name,
   CASE
   WHEN MAX(A.Zip) IS NULL THEN Max(C.Zip)
   ELSE MAX(A.Zip)
   END Zip,
   CASE 
   WHEN MAX(A.City) IS NULL THEN Max(C.City) 
   ELSE MAX(A.City) 
   END City,
   A.Mdate
   FROM @table_a A
   INNER JOIN @Table_B B ON A.ID = B.ID
   INNER JOIN @table_c C ON B.RollNo = C.RollNo
   GROUP BY A.ID,A.Mdate
   order by A.Mdate
   ) C 


   drop table #temp;

如果需要在C派生表中的Mdate上排序,我将使用一个变量,该变量是根据您要在#temp表中更新的行数的计数构建的,以填充子查询中的top语句。这样,您可以控制顺序。

© www.soinside.com 2019 - 2024. All rights reserved.