SQL Query навсегда зависает при объединении десятичных (8,0) полей - PullRequest
0 голосов
/ 06 июля 2010

У меня есть следующий запрос, который отлично работает:

SELECT      TMP_CLPUD.dbo.FormatS(RIGHT(SV1.VASLOC, 7), 9, 0) AS C_ACCOUNT, 
        TMP_CLPUD.dbo.FormatS(Cust.C_CUSTOMER, 7, 0) AS C_CUSTOMER, 
        CA.OID, 
        CN2.NBCUNQ AS CUNQ, 
        CN2.NBSUNQ AS SUNQ, 
        'AC' AS C_STATUS,
        TMP_CLPUD.dbo.mmsDATE(CN2.NBCNTE) AS IN_DATE, 
        TMP_CLPUD.dbo.mmsDATE(CN2.NBDSTE) AS OUT_DATE, 
        0 AS ARCHIVE
FROM        BILLING.SVP00100 AS SV1 INNER JOIN BILLING.CNP00200 AS CN2 ON SV1.VASUNQ = CN2.NBSUNQ
                                INNER JOIN BILLING.CMP00100 AS CM1 ON CN2.NBCUNQ = CM1.KACUST
                                INNER JOIN BILLING.CustomerAccounts AS CA ON CM1.KACUST = CA.CustomerNbr
                                INNER JOIN TMP_CLPUD.dbo.tblCustomers As Cust ON CA.OID = Cust.OID
                                INNER JOIN BILLING.Customers AS C ON CA.OID = C.OID
                                INNER JOIN BILLING.CNP00100 AS CN1 ON CN2.NBCUNQ = CN1.NACUNQ AND CN2.NBSUNQ = CN1.NASUNQ
ORDER BY C_ACCOUNT, C_CUSTOMER

Однако, если я попытаюсь связать еще одно поле между CN1 и CN2, запрос будет зависать бесконечно.Поле имеет тип decimal (8,0) в обеих таблицах и не допускает пустых значений.Вот запрос с третьей ссылкой на месте:

SELECT      TMP_CLPUD.dbo.FormatS(RIGHT(SV1.VASLOC, 7), 9, 0) AS C_ACCOUNT, 
        TMP_CLPUD.dbo.FormatS(Cust.C_CUSTOMER, 7, 0) AS C_CUSTOMER, 
        CA.OID, 
        CN2.NBCUNQ AS CUNQ, 
        CN2.NBSUNQ AS SUNQ, 
        'AC' AS C_STATUS,
        TMP_CLPUD.dbo.mmsDATE(CN2.NBCNTE) AS IN_DATE, 
        TMP_CLPUD.dbo.mmsDATE(CN2.NBDSTE) AS OUT_DATE, 
        0 AS ARCHIVE
FROM        BILLING.SVP00100 AS SV1 INNER JOIN BILLING.CNP00200 AS CN2 ON SV1.VASUNQ = CN2.NBSUNQ
                                INNER JOIN BILLING.CMP00100 AS CM1 ON CN2.NBCUNQ = CM1.KACUST
                                INNER JOIN BILLING.CustomerAccounts AS CA ON CM1.KACUST = CA.CustomerNbr
                                INNER JOIN TMP_CLPUD.dbo.tblCustomers As Cust ON CA.OID = Cust.OID
                                INNER JOIN BILLING.Customers AS C ON CA.OID = C.OID
                                INNER JOIN BILLING.CNP00100 AS CN1 ON CN2.NBCUNQ = CN1.NACUNQ AND CN2.NBSUNQ = CN1.NASUNQ AND CN2.NBCNTE = CN1.NACNTE
ORDER BY C_ACCOUNT, C_CUSTOMER

Я переписал эту вещь так много разных способов, как только мог подумать, но каждый раз, когда я пытаюсь связать это третье поле, оно просто зависает навсегда.Есть предложения?

Ответы [ 2 ]

1 голос
/ 06 июля 2010

Если вы собираетесь сравнивать числа с плавающей запятой для точного соответствия, вы обычно напрашиваетесь на неприятности. Один из способов преодоления этого состоит в том, чтобы взять абсолютное значение разности двух чисел и сравнить его с эпсилоном, скажем, 1e-9, и если разность меньше или равна этому эпсилону, то вы можете предположить, что 2 плавающих номера точек равны.

EDIT Как указывает Лассе, попытка присоединиться к этим столбцам будет бесполезной, используя технику, описанную выше. Если вам действительно нужна эта возможность соединения, другой подход заключается в том, чтобы не хранить числа как числа с плавающей запятой, а сохранять их как целые числа. Так, например, если бы это была валюта доллара, вы могли бы хранить 123,45 доллара как 12345. 99,01 доллара были бы сохранены как 9901. Затем вы могли бы объединить целочисленные значения, что позволило бы избежать всех головных болей с числами с плавающей запятой. Чтобы преобразовать целые числа обратно в соответствующие им значения с плавающей запятой, вы просто делите на некоторую константу (100 в примере с долларовой валютой).

Но я бы спросил, почему вы присоединяетесь к этим типам ценностей, это кажется странным.

0 голосов
/ 06 июля 2010

Равенство всегда немного схематично с числами с плавающей запятой.Если вы представляете что-то вроде денежных транзакций, вам, как правило, лучше хранить их в целочисленном виде, например, в центах (или десятых долях цента, или любой другой самой маленькой монете, с которой вы хотите иметь дело).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...