我有一个包含DOC1,DOC2和CLIENT列的数据库表。我正在尝试为每个CLIENT选择一行,其DOC1列根据以下顺序从最高到最低优先级具有最高优先级:ITCI> ITPP> ITPS> ITPT。
这里是一个例子。
输入
DOC1 DOC2 CLIENT
ITCI GG319 101
ITPS YB311 102
ITPT GG319 101
ITPP YB311 102
输出
目标表的CLIENT必须具有唯一键,我必须通过选择具有最高优先级DOC1的行来添加两列DOC1和DOC2。
CLIENT DOC2 DOC1
101 GG319 ITCI
102 YB311 ITPP
我在结束例程中编写了一个select single,但是存在语法错误:
Select single doc1 doc2 (W_doc1, W_doc2)
FROM /BI0/Pdoctax
WHERE client eq <RESULT_FIELDS>-client.
答案 0 :(得分:1)
由于您的优先顺序从最高到最低完全类似于字母顺序,因此您只需要使用GROUP BY和MIN聚合:
SELECT client, MIN( doc2 ) AS doc2, MIN( doc1 ) AS doc1
INTO TABLE @DATA(itab)
FROM /BI0/Pdoctax
GROUP BY client.
在排序规则不是原始的更复杂的情况下,可以使用CASE
子句。
答案 1 :(得分:0)
如果我理解这一权利,则您希望选择项每个CLIENT仅输出一行行,并根据那些DOC1优先级从原始表中选择行。
这样的选择是不可能的。
在我的头上,这些是我想出的可能性,但可能还有更多。根据您的情况,您将必须找出最适合您的需求。
您可以选择所有内容,对其进行遍历,并使用IF条件等创建格式。
如果确实只有这4种DOC1,则可以选择所有内容,按CLIENT和DOC1对内部表进行排序,然后删除仅比较CLIENT的邻接重复项。这将起作用,因为“ ITCI> ITPP> ITPS> ITPT”是按字母顺序排列的。
同样,如果您只有这4种DOC1可能性,则可以彼此选择它们,检查是否还有缺少的CLIENTS。
答案 2 :(得分:0)
由于您的doc1优先级值实际上是6,所以应该可以。
SELECT b~client,
coalesce( p1~doc1, p2~doc1, p3~doc1, p4~doc1, p5~doc1, p6~doc1 ),
coalesce( p1~doc2, p2~doc2, p3~doc2, p4~doc2, p5~doc2, p6~doc2 )
FROM /bi0/pdoctax AS b
LEFT OUTER JOIN /bi0/pdoctax AS p1
ON p1~client = b~client
AND p1~doc1 = 'ITCI'
LEFT OUTER JOIN /bi0/pdoctax AS p2
ON p2~client = b~client
AND p2~doc1 = 'ITPS'
LEFT OUTER JOIN /bi0/pdoctax AS p3
ON p3~client = b~client
AND p3~doc1 = 'ITPT'
LEFT OUTER JOIN /bi0/pdoctax AS p4
ON p4~client = b~client
AND p4~doc1 = 'ITPT'
LEFT OUTER JOIN /bi0/pdoctax AS p5
ON p4~client = b~client
AND p4~doc1 = 'P5'
LEFT OUTER JOIN /bi0/pdoctax AS p6
ON p4~client = b~client
AND p4~doc1 = 'P6'
WHERE b~client = @<result_fields>-client
INTO @DATA(ls_doctax).
我假设您正在寻找在单个SELECT语句中执行此操作的答案,否则可以循环:
DATA lt_priorities TYPE STANDARD TABLE OF /bi0/pdoctax-doc1.
lt_priorities = VALUE #( ( 'ITCI' ) ( 'ITPS' ) ( 'ITPT' ) ( 'ITPP' ) ( 'P500' ) ( 'P600' ) ).
SELECT b~client,
doc1,
doc2
FROM /bi0/pdoctax AS b
WHERE b~client = @<result_fields>-client
ORDER BY doc1 ASCENDING
INTO TABLE @DATA(lt_doctax).
DATA ls_doctax_filtered LIKE LINE OF lt_doctax.
LOOP AT lt_priorities ASSIGNING FIELD-SYMBOL(<fs_priority>).
READ TABLE lt_doctax ASSIGNING FIELD-SYMBOL(<fs_doctax>)
WITH KEY doc1 = <fs_priority> BINARY SEARCH.
IF sy-subrc = 0.
ls_doctax_filtered = <fs_doctax>.
* --->
EXIT.
ENDIF.
ENDLOOP.
答案 3 :(得分:0)
这是ABAP 7.52的“简单”解决方案。
我使用了另一个示例进行测试,以便任何人都可以使用它:我使用了ABAP安装随附的演示表SFLIGHT
。如果表为空,请运行程序SAPBC_DATA_GENERATOR
来生成数据。
正如其他人已经提到的那样,假定您的优先级基于字母顺序,因此可以使用聚合函数MIN
。
下面的代码获取SFLIGHT
行,这些行与CARRID列的每个不同值(相当于您的问题中的CLIENT)及其在PAYMENTSUM(DOC1)列中的最小值(都位于{{1 }}子查询):
EXISTS
数据库表SELECT carrid, fldate AS doc2, paymentsum AS doc1
FROM sflight AS a
WHERE EXISTS (
SELECT carrid
FROM sflight
WHERE carrid = a~carrid
GROUP BY carrid
HAVING MIN( paymentsum ) = a~paymentsum )
INTO TABLE @DATA(itab).
的内容(通过SE16 /预期结果突出显示):
关于ABAP SQL代码的说明:
itab
的多行具有相同的CARRID和PAYMENTSUM值,则将随机选择其中一行(经典SQL规则)。SFLIGHT
(ABAP SQL 7.53之前不允许)