连接到没有范围但需要范围的表

发布于 2024-11-27 15:44:52 字数 1900 浏览 2 评论 0原文

试图找到编写此 SQL 语句的最佳方法。

我有一个客户表,其中包含该客户的内部信用评分。然后我有另一个表,其中包含该信用评分的定义。我想将这些表连接在一起,但第二个表没有任何方法可以轻松链接它。

客户的分数是 1-999 之间的整数,定义表具有以下列:

Score
Description

这些行:

60   LOW
99   MED
999  HIGH

所以基本上,如果客户的分数在 1 到 60 之间,则为低分,61-99 为中分,为 100 分-999 他们很高。

我无法真正 INNER JOIN 这些,因为只有当分数为 60、99 或 999 时它才会加入它们,并且这会排除具有这些分数的其他任何人。

我不想用静态数字做一个 case 语句,因为我们的分数将来可能会发生变化,并且我不想在/如果他们这样做时更新我的​​初始查询。我也无法创建任何表或函数来执行此操作 - 我需要创建一个 SQL 语句来为我执行此操作。

编辑:

一位同事说这可行,但有点疯狂。我认为必须有更好的方法:

SELECT 
  internal_credit_score
  (
    SELECT
      credit_score_short_desc
    FROM
      cf_internal_credit_score
    WHERE
      internal_credit_score = (
                                SELECT 
                                  max(credit.internal_credit_score) 
                                FROM 
                                  cf_internal_credit_score credit  
                                WHERE 
                                  cs.internal_credit_score <= credit.internal_credit_score
                                  AND credit.internal_credit_score <= (
                                                                        SELECT
                                                                          min(credit2.internal_credit_score)
                                                                        FROM
                                                                          cf_internal_credit_score credit2
                                                                        WHERE
                                                                          cs.internal_credit_score <= credit2.internal_credit_score
                                                                      )
                              )
  )
FROM 
  customer_statements cs

Trying to find the best way to write this SQL statement.

I have a customer table that has the internal credit score of that customer. Then i have another table with definitions of that credit score. I would like to join these tables together, but the second table doesn't have any way to link it easily.

The score of the customer is an integer between 1-999, and the definition table has these columns:

Score
Description

And these rows:

60   LOW
99   MED
999  HIGH

So basically if a customer has a score between 1 and 60 they are low, 61-99 they are med, and 100-999 they are high.

I can't really INNER JOIN these, because it would only join them IF the score was 60, 99, or 999, and that would exclude anyone else with those scores.

I don't want to do a case statement with the static numbers, because our scores may change in the future and I don't want to have to update my initial query when/if they do. I also cannot create any tables or functions to do this- I need to create a SQL statement to do it for me.

EDIT:

A coworker said this would work, but its a little crazy. I'm thinking there has to be a better way:

SELECT 
  internal_credit_score
  (
    SELECT
      credit_score_short_desc
    FROM
      cf_internal_credit_score
    WHERE
      internal_credit_score = (
                                SELECT 
                                  max(credit.internal_credit_score) 
                                FROM 
                                  cf_internal_credit_score credit  
                                WHERE 
                                  cs.internal_credit_score <= credit.internal_credit_score
                                  AND credit.internal_credit_score <= (
                                                                        SELECT
                                                                          min(credit2.internal_credit_score)
                                                                        FROM
                                                                          cf_internal_credit_score credit2
                                                                        WHERE
                                                                          cs.internal_credit_score <= credit2.internal_credit_score
                                                                      )
                              )
  )
FROM 
  customer_statements cs

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

拥抱没勇气 2024-12-04 15:44:52

试试这个,更改您的表以包含分数范围:

ScoreTable
-------------
LowScore int
HighScore int
ScoreDescription string

数据值

LowScore HighScore ScoreDescription 
-------- --------- ----------------
1        60        Low
61       99        Med
100      999       High

查询:

Select
    .... , Score.ScoreDescription 
    FROM YourTable
    INNER JOIN Score ON YourTable.Score>=Score.LowScore 
        AND YourTable.Score<=Score.HighScore
    WHERE ...

try this, change your table to contain the range of the scores:

ScoreTable
-------------
LowScore int
HighScore int
ScoreDescription string

data values

LowScore HighScore ScoreDescription 
-------- --------- ----------------
1        60        Low
61       99        Med
100      999       High

query:

Select
    .... , Score.ScoreDescription 
    FROM YourTable
    INNER JOIN Score ON YourTable.Score>=Score.LowScore 
        AND YourTable.Score<=Score.HighScore
    WHERE ...
蓝色星空 2024-12-04 15:44:52

假设您的表名为 CreditTable,这就是您想要的:

select * from
(
    select Description, Score
    from CreditTable
    where Score > 80 /*client's credit*/
    order by Score
)
where rownum = 1

此外,请确保您的高分参考值为 1000,即使客户的最高得分可能为 999。

更新

上面的 SQL 为您提供给定值的信用记录。如果您想加入,例如,Clients 表,您可以执行以下操作:

select 
  c.Name,
  c.Score,
  (select Description from 
      (select Description from CreditTable where Score > c.Score order by Score)
   where rownum = 1)
from clients c

我知道这是为每个返回行执行的子选择,但话又说回来,CreditTable 非常小,并且不会因为子选择的使用而造成显着的性能损失。

Assuming you table is named CreditTable, this is what you want:

select * from
(
    select Description, Score
    from CreditTable
    where Score > 80 /*client's credit*/
    order by Score
)
where rownum = 1

Also, make sure your high score reference value is 1000, even though client's highest score possible is 999.

Update

The above SQL gives you the credit record for a given value. If you want to join with, say, Clients table, you'd do something like this:

select 
  c.Name,
  c.Score,
  (select Description from 
      (select Description from CreditTable where Score > c.Score order by Score)
   where rownum = 1)
from clients c

I know this is a sub-select that executed for each returning row, but then again, CreditTable is ridiculously small and there will be no significant performance loss because of the the sub-select usage.

落墨 2024-12-04 15:44:52

您可以使用分析函数将分数描述表中的数据转换为范围(我假设您的意思是 100-999 应该映射到“高”,而不是 99-999)。

SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2    select 60 score, 'Low' description from dual union all
  3    select 99, 'Med' from dual union all
  4    select 999, 'High' from dual
  5  )
  6  select description,
  7         nvl(lag(score) over (order by score),0) + 1 low_range,
  8         score high_range
  9*   from x
SQL> /

DESC  LOW_RANGE HIGH_RANGE
---- ---------- ----------
Low           1         60
Med          61         99
High        100        999

然后,您可以使用类似的内容将其加入到您的 CUSTOMER 表中

SELECT c.*, 
       sd.*
  FROM customer c,
       (select description,
               nvl(lag(score) over (order by score),0) + 1 low_range,
               score high_range
          from score_description) sd
 WHERE c.credit_score BETWEEN sd.low_range AND sd.high_range

You can use analytic functions to convert the data in your score description table to ranges (I assume that you meant that 100-999 should map to 'HIGH', not 99-999).

SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2    select 60 score, 'Low' description from dual union all
  3    select 99, 'Med' from dual union all
  4    select 999, 'High' from dual
  5  )
  6  select description,
  7         nvl(lag(score) over (order by score),0) + 1 low_range,
  8         score high_range
  9*   from x
SQL> /

DESC  LOW_RANGE HIGH_RANGE
---- ---------- ----------
Low           1         60
Med          61         99
High        100        999

You can then join this to your CUSTOMER table with something like

SELECT c.*, 
       sd.*
  FROM customer c,
       (select description,
               nvl(lag(score) over (order by score),0) + 1 low_range,
               score high_range
          from score_description) sd
 WHERE c.credit_score BETWEEN sd.low_range AND sd.high_range
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文