【问题标题】:Assistance with SQL script协助使用 SQL 脚本
【发布时间】:2020-01-24 10:37:53
【问题描述】:

我目前正在设计一个SQL 报告,从ERP system 内部运行。这段代码背后的想法是,将所有 AR 打开项目,所有这些字段都放在 SELECT statement 中,并且能够选择要运行报告的对象,通过我描述的各种 WHERE 子句选项。

我还附上了 ERP system 内的表格,带有“参数”名称,以及用户必须将报告运行为...的选项...

根据搜索条件,我无法让所有这些 CASE ANDOR 声明发挥作用,或提供特定数据。 p>

我什至不确定我是否在 WHERE 子句代码上正确显示了参数(使用“< >,或按字段名称,或使用 ' ' , ...)

Sample Data

Report parameters

SELECT DISTINCT
e1.rel_value AS Cust_Rep_Grp, 
o1.description AS Cust_Rep_Grp_Name, 
r.main_apar_id AS Head_Office, 
o2.description AS Head_Office_Name, 
s.apar_id AS CustID, 
o3.description AS Cust_ID_Name, 
s.voucher_no, 
s.dim_2 AS BookingNo, 
h.ext_ord_ref AS YourRef,  
n.booking_day_fx AS Booking_date, 
n.check_in_date_fx AS Check_in_date, 
n.check_out_date_fx AS Check_out_date, 
s.voucher_date AS Invoice_date,
s.due_date, 
i.art_descr AS Hotel_name, 
o.description AS Destination,
e2.rel_value AS City,
o.description AS City_name,
e.rel_value AS Country_code,
o4.description AS Country_name, 
n.guest_fx AS Client_name,
n.pax_fx, 
s.currency,
i.disc_percent AS Comm_percentage, 
s.cur_amount AS Net_amt, 
s.rest_curr AS Due_now,
s.voucher_type,
s.order_id 
FROM acutrans s
LEFT OUTER JOIN acuheader r
ON r.client = s.client
AND s.apar_id = r.apar_id
LEFT OUTER JOIN asoheader h
ON h.client = s.client
AND h.order_id = s.order_id
LEFT OUTER JOIN asodetail i
ON i.client = s.client
AND i.order_id = s.order_id
INNER JOIN algvirelvalue e2 
ON e2.client= s.client 
AND e2.rel_attr_id='ZZ06'
AND e2.related_attr = 'CITY' 
AND i.article = e2.article
LEFT OUTER JOIN aglrelvalue e 
ON e.client= s.client 
AND e.attribute_id = 'ZZ06'
AND e.rel_attr_id = 'C9'
AND e.att_value = e2.rel_value
LEFT OUTER JOIN aglrelvalue e1
ON e1.client = s.client
AND e1.attribute_id = 'A4'
AND e1.rel_attr_id = 'ZG06'
AND e1.att_value = s.apar_id
LEFT OUTER JOIN agldescription o 
ON o.client= s.client 
AND o.attribute_id='ZZ06' 
AND o.dim_value = e2.rel_value
LEFT OUTER JOIN agldescription o1 
ON o1.client= s.client 
AND o1.attribute_id='ZG06' 
AND o1.dim_value = e1.rel_value
LEFT OUTER JOIN agldescription o2 
ON o2.client= s.client 
AND o2.attribute_id='A4' 
AND o2.dim_value = r.main_apar_id
LEFT OUTER JOIN agldescription o3 
ON o3.client= s.client 
AND o3.attribute_id='A4' 
AND o3.dim_value = s.apar_id 
LEFT OUTER JOIN agldescription o4 
ON o4.client= s.client 
AND o4.attribute_id='C9' 
AND o4.dim_value = e.rel_value
LEFT OUTER JOIN afxbooking_gen n 
ON s.dim_2 = n.dim_value 
AND s.client = n.client 
AND n.attribute_id = 'ZZ01'

WHERE  
      CASE WHEN '<checkin_from>' IN (' ','') THEN '*' ELSE '<checkin_from>' END LIKE n.check_in_date_fx
      AND  
      CASE WHEN n.check_in_date_fx IN (' ','') THEN '*' ELSE n.check_in_date_fx END LIKE n.check_in_date_fx
      OR
      CASE WHEN s.voucher_date IN (' ','') THEN '*' ELSE s.voucher_date END LIKE s.voucher_Date
      AND 
      CASE WHEN s.voucher_date IN (' ','') THEN '*' ELSE s.voucher_date END LIKE s.voucher_Date
      OR 
      CASE WHEN n.booking_day_fx IN (' ','') THEN '*' ELSE n.booking_day_fx END LIKE n.booking_day_fx
      AND
      CASE WHEN n.booking_day_fx IN (' ','') THEN '*' ELSE n.booking_day_fx END LIKE n.booking_day_fx
      OR 
      CASE WHEN n.check_out_date_fx IN (' ','') THEN '*' ELSE n.check_out_date_fx END LIKE n.check_out_date_fx
      AND 
      CASE WHEN n.check_out_date_fx IN (' ','') THEN '*' ELSE n.check_out_date_fx END LIKE n.check_out_date_fx  
      OR 
      CASE WHEN s.apar_id  IN (' ','') THEN '*' ELSE s.apar_id  END LIKE s.apar_id 
      AND
      CASE WHEN s.apar_id  IN (' ','') THEN '*' ELSE s.apar_id  END LIKE s.apar_id 
      OR 
      CASE WHEN o3.description IN (' ','') THEN '*' ELSE o3.description END LIKE o3.description
      OR 
      CASE WHEN e1.rel_value IN (' ','') THEN '*' ELSE e1.rel_value END LIKE e1.rel_value
      AND
      CASE WHEN e1.rel_value IN (' ','') THEN '*' ELSE e1.rel_value END LIKE e1.rel_value
      OR 
      CASE WHEN o1.description IN (' ','') THEN '*' ELSE o1.description END LIKE o1.description 
      OR 
      CASE WHEN r.main_apar_id IN (' ','') THEN '*' ELSE r.main_apar_id END LIKE r.main_apar_id
      AND
      CASE WHEN r.main_apar_idIN (' ','') THEN '*' ELSE r.main_apar_id END LIKE r.main_apar_id
      OR 
      CASE WHEN o2.description IN (' ','') THEN '*' ELSE o2.description END LIKE o2.description  
      OR 
      CASE WHEN s.dim_2 IN (' ','') THEN '*' ELSE s.dim_2 END LIKE s.dim_2
      AND
      CASE WHEN s.dim_2 IN (' ','') THEN '*' ELSE s.dim_2 END LIKE s.dim_2
      OR 
      CASE WHEN e.rel_value IN (' ','') THEN '*' ELSE e.rel_value END LIKE e.rel_value  
      OR 
      CASE WHEN s.currency  IN (' ','') THEN '*' ELSE s.currency  END LIKE s.currency  
      OR 
      CASE WHEN n.guest_fx IN (' ','') THEN '*' ELSE n.guest_fx END LIKE n.guest_fx 
      OR 
      CASE WHEN s.voucher_no IN (' ','') THEN '*' ELSE s.voucher_no END LIKE s.voucher_no
      AND
      CASE WHEN s.voucher_no IN (' ','') THEN '*' ELSE s.voucher_no END LIKE s.voucher_no
      OR 
      CASE WHEN h.ext_ord_ref IN (' ','') THEN '*' ELSE h.ext_ord_ref END LIKE h.ext_ord_ref
      OR 
      CASE WHEN s.order_id IN (' ','') THEN '*' ELSE s.order_id END LIKE s.order_id
      AND
      CASE WHEN s.order_id IN (' ','') THEN '*' ELSE s.order_id END LIKE s.order_id

【问题讨论】:

  • 您从哪个平台或语言执行此查询? where 子句不起作用,因为它与自身匹配(这始终是正确的,您根本没有比较参数
  • 您是说当参数值为空时,您不想对该列进行过滤?
  • @ChrisSchaller 来自 Unit4 Business World,报告引擎。如何在 WHERE CLAUSE 中正确编写参数,以允许用户选择 1 或各种?谢谢
  • @ChrisSchaller 当参数值为空时,将其全部从该参数中取出...但仍然过滤用户输入的任何参数
  • 您已经组合了日期边界过滤器和文本过滤器。日期过滤器是否应该完全匹配,或者您是否希望用户指定日期范围,以便返回 checkin 日期介于 checkin_fromcheckin_to 之间的所有记录?

标签: sql left-join case where-clause


【解决方案1】:

从哪里开始?

让我们稍微简化一下。

  1. 没有WHERE 子句的SELECT 语句是否返回正确的结构。因此,如果所有这是在这样的论坛中调试的大型查询,那么我们需要针对响应,对于此解决方案的其余部分,我们将假设您的 SELECT FROMJOIN 语法和链接是正确的。

  2. 您的WHERE 标准根本不正确,它根本没有与输入参数进行比较。
    您的过滤条件似乎可以总结为一些日期和数字范围过滤器与一些文本和数字完全匹配过滤器之间的联合。每个过滤器都是可选的,但返回的数据必须满足所有不为空的参数。

    Unit4 Business World, Report Engine中的参数语法我不熟悉,下面是纯MS SQL的例子。参数将以@为前缀,Unit4可能有自定义参数实现,你需要查看文档。

    作为一般规则,在调试WHERE 条件时,注释掉除第一个条件之外的所有条件会有所帮助,然后递增地附加条件,每次检查输出是否符合预期,然后再添加下一个条件。

我可以确定以下概念性过滤条件:

  1. (签入日期)n.check_in_date_fx 必须大于等于@checkin_from
  2. n.check_in_date_fx 必须小于等于 @checkin_to
  3. s.voucher_date 必须 >= @invdate_from
  4. s.voucher_date 必须是 @invdate_to
  5. n.booking_day_fx 必须 >= @bookdate_fro
  6. n.booking_day_fx 必须是 @bookdate_to
  7. n.check_out_date_fx 必须 >= @checkout_fro
  8. n.check_out_date_fx 必须是 @checkout_to
  9. (客户 ID)s.apar_id 必须 >= @custid_from
  10. s.apar_id 必须是 @custid_to
  11. (客户名称)o3.descriptionLIKE@custname ...

让我们停下来...我们需要AND每个条件,因为它们必须都匹配,但是我们可以使用括号并为每个过滤器添加一个子OR条件,这样它们就成对了:

在哪里
parameter1empty OR 过滤条件,用于 parameter1 匹配) ANDparameter2empty OR 过滤条件,用于 parameter2 匹配) ANDparameter3empty OR parameter3 匹配的过滤条件)

因此,对于我们确定的第一个过滤器,WHERE 子句如下所示:

这假设 date 字段实际上存储为DATE 兼容的数据类型,如果它们存储为文本,则以下将不起作用... 另外假设参数是作为字符串传入的,如果它们作为日期类型传入,那么IN (' ','') 将不起作用,您将不得不使用null 日期比较。

WHERE  
    ( @checkin_from IN (' ','') OR n.check_in_date_fx >= @checkin_from )
AND ( @checkin_to IN (' ','') OR n.check_in_date_fx <= @checkin_to )      
AND ( @invdate_from IN (' ','') OR s.voucher_date >= @invdate_from )
AND ( @invdate_to IN (' ','') OR s.voucher_date <= @invdate_to )
AND ( @bookdate_fro IN (' ','') OR n.booking_day_fx >= @bookdate_fro )
AND ( @bookdate_to IN (' ','') OR n.booking_day_fx <= @bookdate_to )
AND ( @checkout_fro IN (' ','') OR n.check_out_date_fx >= @checkout_fro )
AND ( @checkout_to IN (' ','') OR n.check_out_date_fx <= @checkout_to )
AND ( @custid_from IN (' ','') OR s.apar_id >= @custid_from )
AND ( @custid_to IN (' ','') OR s.apar_id <= @custid_to )
AND ( @custname IN (' ','') OR o3.description LIKE @custname )
...

您只需继续使用AND 附加新条件,确保在_内部有一个条件可以匹配空参数值OR,该参数与该行匹配。

如果日期参数作为字符串传入,并且数据库字段存储为 date absed 数据类型,那么上述语法应该可以工作。如果日期参数实际上是作为正确的DATE 类型值传入的,那么字符串比较可能不起作用,空日期可能会作为NULL 传入,如果是这种情况,那么您可能需要更改参数逻辑像这样:

AND ( @checkin_to IS NULL OR ... )

如果日期字段未存储为日期,则必须将它们转换为日期以允许基于日期的比较、基于字符串的大于小于仅当日期以 ISO 格式一致存储时,比较才会起作用

希望本次讨论能够为您指明正确的方向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 2018-10-22
    • 1970-01-01
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多