回答

收藏

如何在SQL Server查询此输出

技术问答 技术问答 195 人阅读 | 0 人回复 | 2023-09-14

我有一个像这样的数据表:+ s& a; S5 _% d; X+ J' f1 e
CREATE TABLE Test    (CustName varchar(20),Country varchar(20),RecordedTime datetime,CurrNo tinyint);INSERT INTO Test    (CustName,Country,RecordedTime,CurrNo)VALUES Alex','Australia','2018-06-01 08:00:00,1)Alex','China','2018-06-  (Alex','India','2018-06-01 10:05:00,3)Alex','Japan','2018-06-01 1:00:00,4)John','Australia','2018-06-01 08:00:00,1)John','China','2018-06-02 08:00:00,2)Bob','Australia','2018-06-02 09:00:00,1)Bob','Brazil','2018-06-03 09:50:00,2)Bob','Africa','2018-06-03 1:50:00,3)Bob','India','2018-06-03 1:55:00,4)Tim','Brazil','2018-06-  (Tim','Cuba','2018-06-11 00:00:00,3)Tim','India','2018-06-  (Jerry','Cuba','2018-06-  (Jerry','Brazil','2018-06-12 00Jerry','India','2018-06-  (Jerry','USA','2018-06-12 00:15:00,9)  Maulik','Aus','2018-06-  ('')Maulik','Eng','2018-06-  (Maulik','USA','2018-06-  (Maulik','Ind','2018-06-6);表结果:- q" D0 e' ]3 h5 Y
    CustName    Country    RecordedTime           CurrNo -----------------------------------------------------  Alex        Australia  2018-Jun-01 08:00 AM    1  Alex        China   20188年                20188年-Jun-01 10:00 AM    2  Alex        India   20188年                20188年-Jun-01 10:05 AM   3  Alex        Japan   20188年                20188年-Jun-01 11:00 AM   4  John        Australia  2018-Jun-01 08:00 AM    1  John        China   20188年                20188年-Jun-02 08:00 AM    2  Bob         Australia  2018-Jun-02 09:00 AM    1  Bob         Brazil     2018-Jun-03 09:50 AM    2  Bob         Africa     2018-Jun-03 11:50 AM   3  Bob         India   20188年                20188年-Jun-03 11:55 AM   4  Tim         Brazil     2018-Jun-10 12:00 AM    2  Tim         Cuba    20188年                20188年-Jun-11 12:00 AM   3  Tim         India   20188年                20188年-Jun-11 12:05 AM   4  Jerry       Cuba    20188年                20188年-Jun-12 12:00 AM   4  Jerry       Brazil     2018-Jun-12 12:05 AM   5  Jerry       India   20188年                20188年-Jun-12 12:10 AM    7  Jerry       USA     20188年                20188年-Jun-12 12:15 AM    9  Maulik      Aus     20188年                20188年-Jun-12 00:00:AM   3  Maulik      Eng     20188年                20188年-Jun-13 00:00:AM   4  Maulik      USA     20188年                20188年-Jun-14 00:00:AM   5  Maulik      Ind     20188年                20188年-Jun-14 00:00:AM    6我需要涵盖以下所有方案的输出。
" ~1 W4 A  a6 H; c如何显示审计和历史记录字段记录字段的经验法则;) d3 m: n' K) b3 j# d+ P! }
[ol]记录仅针对 原始帐户    应具有Audit =“ ADD”或“ CHANGE”&History =“ NEW”,“ BEFORE”或“ CURRENT (这意味着表中的条目必须从CurrNo = 1开始)! J0 Y& \4 R4 t
对于这类账户,记录不应针对 迁移帐户的    Audit =“ ADD”和History =“ NEW (这意味着表中的条目不是从CurrNo = 1开始,它可以从2或3或任何升序开始)审计应该是 CHANGE而 History BEFORE”或“ CURRENT” 7 k! J8 m* U7 V, E( X% E3 L
[/ol]方案1    :如果给定输入日期为2018年6月1日,则输出应如下(即当同一天多次添加和编辑记录时)0 U# H- [, E+ F. {- B; {
CustName    Country    RecordedTime           Audit    History  ----------------------------------------------------------------   Alex        Australia  2018-Jun-01 08:00 AM   ADD      NEW   Alex        Australia  2018-Jun-01 08:00 AM   CHANGE   BEFORE   Alex        Japan   20188年                20188年-Jun-01 11:00 AM   CHANGE   CURRENT   John        Australia  2018-Jun-01 08:00 AM   ADD      NEW方案2    :如果给定输入日期为2018年6月2日,输出应如下(即当前几天有记录,今天编辑同一记录,今天有新记录)
" Y, S1 s* a9 {6 c& B( ]- M            CustName    Country    RecordedTime           Audit    History  -----------------------------------------------------------------   John        Australia  2018-Jun-01 08:00 AM   CHANGE   BEFORE   John        China   20188年                20188年-Jun-02 08:00 AM   CHANGE   CURRENT   Bob         Australia  2018-Jun-02 09:00 AM   ADD      NEW方案3
. I+ j4 Q7 A! l6 o% R: J:如果给定输入日期为2018年6月3日,则输出应如下(即当记录在同一天多次编辑时,应列出最后一个日期的最后一个记录,然后列出当前给定的最后一个记录)1 _" [, g6 ~; P
            CustName    Country    RecordedTime           Audit    History  ----------------------------------------------------------------   Bob         Australia  2018-Jun-02 09:00 AM   CHANGE   BEFORE   Bob         India   20188年                20188年-Jun-03 12:55 AM   CHANGE   CURRENT方案4    :如果给定输入日期为2018年6月10日,则输出应如下所示
3 g% ~' F8 U' W# e. \8 n            CustName    Country    RecordedTime           Audit    History  ----------------------------------------------------------------   Tim         Brazil     2018-Jun-10 12:00 AM    CHANGE   CURRENT方案5    :如果给定输入日期为2018年6月11日,则输出应如下(类似方案2)$ u5 b6 |1 f6 t. f! ]' P
            CustName    Country    RecordedTime           Audit    History  ----------------------------------------------------------------   Tim         Brazil     2018-Jun-10 12:00 AM    CHANGE   BEFORE   Tim         India      2018-Jun-11 12:05 AM    CHANGE   CURRENT方案6    :如果输入日期为2018年6月12日,则输出如下(类似于方案3)
3 m$ M1 d9 U) K: M  B! ~8 |            CustName    Country    RecordedTime           Audit    History  ----------------------------------------------------------------    Jerry       Cuba        20188年 201888年                                                                2018820188-Jun-12 12:00 AM    CHANGE   BEFORE    Jerry       USA                                20188年  20188-Jun-12 12:15 AM    CHANGE   CURRENT    Maulik      Aus            20188年  20188-Jun-12 00:00 AM    CHANGE   CURRENT如果输入日期为2018年6月13日,则输出应为以下内容' v! d9 d& Z  N5 v
            CustName    Country    RecordedTime           Audit    History  ----------------------------------------------------------------    Maulik      Aus        2018-Jun-12 00:00 AM    CHANGE   BEFORE    Maulik      Eng        2018-Jun-13 00:00 AM    CHANGE   CURRENT如果输入日期为2018年6月14日,则输出应为以下内容
/ U6 x* x% R. q  N6 [# B6 e            CustName    Country    RecordedTime           Audit    History  ----------------------------------------------------------------    Maulik      Eng            20188年  20188-Jun-13 00:00 AM    CHANGE   BEFORE    Maulik      Ind            20188年  20188-Jun-14 00:00 AM    CHANGE   CURRENT以下是我正在使用的当前代码(满足场景2和3,但不满足其他部分);, T4 t' D4 J' q6 x# Z' v, X
declare @d date='2018-Jun-03'; with Indexer as  select         *,        rn= row_number() over(partition by CustName order by RecordedTime),       rn2=row_number() over(partition by CustName order by RecordedTime desc)    from records),GetValidCustomerRecords as(    select         CustName,       Country,       RecordedTime,       Audit   = case when cast(RecordedTime as date)=@d and rn=1 then 'add' else 'change' end,    RecordedTimeRecordedTime任何SQL专家可以修改此查询以满足所有情况?非常感谢。
* g: `" L' D* l* `0 Q$ e6 x                                                               
6 O" e1 L, f8 u4 k; z& v    解决方案:                                                                1 F5 u( E  @( P' t6 B
                                                                再会,
) H5 K' c$ Z' z请检查以下解决方案是否满足您的所有需求。我用你的数据和更多的行来测试它,但最好重新检查它。乍一看,它似乎回到了要求的结果。稍后我会添加一些解释
$ s0 I( ]% g# y7 B我用它的查询:, i/ Q# P4 a' z+ V' E
DECLARE @Date DATE = '2018-06-12';with MyCTE as  SELECT         t.CustName,t.Country,t.RecordedTime,t.CurrNo,D = CONVERT(DATE,RecordedTime) RN_D = ROW_NUMBER()          OVER (partition by t.CustName order by t.CurrNo desc) RN = ROW_NUMBER()          OVER (partition by t.CustName order by t.CurrNo) RN_Old = ROW_NUMBER()          OVER (partition by t.CustName,(CASE WHEN CONVERT(DATE,RecordedTime)             and D = @Date    where         RN_D =              or (RN = 1 and D = @Date)         or (RN_Old = 1 and D 为了简化测试,我将整个查询插入表函数
. j5 G# j+ W7 O8 ZDROP FUNCTION IF EXISTS dbo.FGOCREATE FUNCTION dbo.F(@Date DATE)RETURNS TABLE AS RETURN (--DECLARE @Date DATE = '2018-06-12';with MyCTE as  SELECT         t.CustName,t.Country,t.RecordedTime,t.CurrNo,D = CONVERT(DATE,RecordedTime) RN_D = ROW_NUMBER()          OVER (partition by t.CustName order by t.CurrNo desc) RN = ROW_NUMBER()          OVER (partition by t.CustName order by t.CurrNo) RRecordedTime)             and D = @Date    where         RN_D =              or (RN = 1 and D = @Date)         or (RN_Old = 1 and D 使用此函数可以更容易地进行多次测试,但在生产环境中,您可能需要使用直接查询  }& Q/ c& I* w3 I
-- Testselect * from F('2018-06-01') order by CustName ,RecordedTimeselect * from F('2018-06-02') order by CustName ,RecordedTimeselect * from F('2018-06-03') order by CustName ,RecordedTimeselect * from F('2018-06-10') order by CustName ,RecordedTimeselect * from F('2018-06-11') order by CustName ,RecordedTimeselect * from F('2018-06-12') order by CustName ,RecordedTimeselect * from F('2018-06-13') order by CustName ,RecordedTimeselect * from F('2018-06-14') order by CustName ,RecordedTime/ **更新于2018-08-19 14:05色列时间**    /
. I: k+ e+ K7 ?我注意到添加一些其他信息是很重要的,以参与这个线程。我希望它能有用* n5 d: ~: ?$ r, f+ p% {
笔记!    在Microsoft SQL Server 2017年开发人员版测试" d1 A% c/ a. v+ R
首先,让我们根据三个查询实施计划比较资源使用的百分比:(1)我的解决方案,(2)更新第一个解决方案后maulik2 r& u) D/ L0 m- N& ?
kansara秒解决方案和(3)maulik kansara第一个解决方案2 F/ K/ X' ?- ~/ Y
查询扫描表11次!
( n- I/ A6 O& Y% j    重要!**
0 h# v. {3 J* u8 Q" s: oEP我们不建议选择查询的唯一参数,但这可能是我们应该检查的第一个信息。此外,我们应该检查它IO以及更多的统计信息和时间统计信息…
9 s+ l' y, \/ d7 I( J: G/ K信用:    使用图像sendryone工具拍摄。有一个免费版本,可以提供大部分DBA所需内容。我用它作为Microsoft
! x# c- L( f% e/ M3 n3 b7 w3 jMVP完整版本的免费获获得的完整版本;-)
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则