2015-07-03 22 views
3

我是Firebird数据库。通过不工作使用“WITH”子句

我有下面的SQL,它连接ShortCode列数据,但没有按照“WITH”子句中的ABC表ORDER_NUMBER列进行排序。

With TBL_SHORT_CODE (SHORT_CODE, FK_KEY) As 
(
SELECT Distinct(XYZ.SHORT_CODE) As SHORT_CODE, ABC.FK_KEY 
From ABC Join XYZ On ABC.PK_KEY = XYZ.FK_KEY 
where XYZ.FK_KEY = '{009DA0F8-51EE-4207-86A6-7E18F96B983A}' And ABC.STATUS_CODE = 1 
Order By ABC.ORDER_NUMBER 
) 


SELECT LIST(Distinct(TBL_SHORT_CODE.SHORT_CODE), ''), ABC.FK_BOM 
From ABC 
Join XYZ ON ABC.FK_KEY = XYZ.PK_KEY 
Join TBL_SHORT_CODE On TBL_SHORT_CODE.FK_KEY = ABC.FK_KEY 
where ABC.FK_BOM = '{009DA0F8-51EE-4207-86A6-7E18F96B983A}' And ABC.STATUS_CODE = 1 
Group By ABC.FK_BOM 

在此先感谢。

祝好!

维沙尔

+0

你ORDER BY是“太早”或无意义的查询处理器 –

+0

只有一个公共表表达式的递归元件可以通过表达包括的命令,或者,使用'TOP'时请参阅http://stackoverflow.com/questions/3924940/sql-cte-and-order-by-affecting-result-set – Ric

+0

@ric在Firebird中,您可以通过在with子句中进行排序,效果只是不能保证(当查询计划中没有其他步骤导致排序时,可能会保留该排序)。在这种情况下,列表(distinct ...)的出现,在不相关字段上的group by以及几个联接都可能导致查询计划导致排序,从而消除with中的排序效应。 –

回答

2

我得到了问题火鸟雅虎组解决。

SQL:

EXECUTE BLOCK RETURNS (SHORT_CODES VARCHAR(2000), FK_BOM INTEGER 
AS 
DECLARE VARIABLE SHORT_CODE1 VARCHAR(2000); 
DECLARE VARIABLE FK_BOM2 INTEGER; 
DECLARE VARIABLE DUMMY INTEGER; 
BEGIN 
    FK_BOM = NULL; 
    FOR With TBL_SHORT_CODE (SHORT_CODE, FK_KEY, ORDER_NUMBER) As 
     (SELECT XYZ.SHORT_CODE, ABC.FK_KEY, min(ABC.ORDER_NUMBER) 
     From ABC Join XYZ On ABC.PK_KEY = XYZ.FK_KEY 
     where XYZ.FK_KEY = '{009DA0F8-51EE-4207-86A6-7E18F96B983A}' And ABC.STATUS_CODE = 1 
     group by 1, 2) 

    SELECT ABC.FK_BOM, tsc.SHORT_CODE, min(tsc.ORDER_NUMBER) 
    From ABC 
    Join XYZ ON ABC.FK_KEY = XYZ.PK_KEY 
    Join TBL_SHORT_CODE tsc On tsc.FK_KEY = ABC.FK_KEY 
    where ABC.FK_BOM = '{009DA0F 8-51EE-4207-86A6-7E18F96B983A}' And ABC.STATUS_CODE = 1 
    Group By 1, 2 
    ORDER BY 1, 3 
    into :FK_BOM2, :SHORT_CODE1, :DUMMY do 
    begin 
     if (FK_BOM2 > FK_BOM) then 
      suspend; 
     if (FK_BOM2 is distinct from FK_BOM) then 
     begin 
      FK_BOM = FK_BOM2; 
      SHORT_CODES = ''; 
     end 
     SHORT_CODES = SHORT_CODES || SHORT_CODE1; 
    end 
    suspend; 
end 
2

ORDER BY不以公共表表达式的功能,你的加盟TBL_SHORT_CODE无论如何都会从中得到任何好处。如果您的订单仅仅是命令的输出,然后改变你的脚本在最终的查询命令:

With TBL_SHORT_CODE (SHORT_CODE, FK_KEY) As 
(
SELECT XYZ.SHORT_CODE As SHORT_CODE, ABC.FK_KEY 
From ABC Join XYZ On ABC.PK_KEY = XYZ.FK_KEY 
where XYZ.FK_KEY = '{009DA0F8-51EE-4207-86A6-7E18F96B983A}' And ABC.STATUS_CODE = 1 
GROUP BY XYZ.SHORT_CODE, ABC.FK_KEY 
) 


SELECT LIST(Distinct(TBL_SHORT_CODE.SHORT_CODE), ''), ABC.FK_BOM 
From ABC 
Join XYZ ON ABC.FK_KEY = XYZ.PK_KEY 
Join TBL_SHORT_CODE On TBL_SHORT_CODE.FK_KEY = ABC.FK_KEY 
where ABC.FK_BOM = '{009DA0F8-51EE-4207-86A6-7E18F96B983A}' And  ABC.STATUS_CODE = 1 
Group By ABC.FK_BOM 
+0

如果我在主SQL中使用Order By ABC.ORDER_NUMBER,那么我得到五个记录我在WITH WITH子句中尝试的原因。我只需要得到一个连接所有Short_Code字段值的记录。任何建议? –

+0

在返回TBL_SHORT_CODE公用表表达式之前,使用GROUP BY将所有重复组合起来。看我的编辑。 – Wibbler

+0

问题是ORDER_NUMBER包含10,20,30,40,50值。这就是为什么我需要避免Group By子句中的ORDER_NUMBER列。 –

0

尝试以下,

with TBL_SHORT_CODE (SHORT_CODE, FK_KEY, FK_BOM, ORDER_NUMBER) As 
(
    SELECT Distinct(XYZ.SHORT_CODE) As SHORT_CODE 
      , ABC.FK_KEY, ABC.FK_BOM, ABC.ORDER_NUMBER 
     From ABC Join XYZ On ABC.PK_KEY = XYZ.FK_KEY 
     where XYZ.FK_KEY = '{009DA0F8-51EE-4207-86A6-7E18F96B983A}' 
     And ABC.STATUS_CODE = 1 
) 


SELECT LIST(Distinct(TBL_SHORT_CODE.SHORT_CODE), ''), A.FK_BOM 
    From TBL_SHORT_CODE A 
where A.FK_BOM = '{009DA0F8-51EE-4207-86A6-7E18F96B983A}' 
    And ABC.STATUS_CODE = 1 
Group By A.FK_BOM 
ORDER BY TBL_SHORT_CODE.ORDER_NUMBER 
+0

如果我删除,那么它会给出一个错误,“ORDER BY子句中的表达式无效(不包含在聚合函数或GROUP BY子句中)”。 –