帮我重写这个查询

发布于 2024-09-12 21:34:17 字数 1444 浏览 4 评论 0原文

我有这样的查询:

SELECT diamond_id, carat, clarity, color, cut,
    CASE clarity
        WHEN "FL" THEN 0
        WHEN "IF" THEN 1
        WHEN "VVS1" THEN 2
        WHEN "VVS2" THEN 3
        WHEN "VS1" THEN 4
        WHEN "VS2" THEN 5
        WHEN "SI1" THEN 6
        WHEN "SI2" THEN 7
        WHEN "I1" THEN 8
        WHEN "I2" THEN 9
        WHEN "I3" THEN 10
        ELSE -1
    END AS clarity_score,
    CASE cut
        WHEN "ideal" THEN 0
        WHEN "excellent" THEN 1
        WHEN "very good" THEN 2
        WHEN "good" THEN 3
        WHEN "fair" THEN 4
        WHEN "poor" THEN 5
        ELSE -1
    END AS cut_score    
    FROM rapnet_diamonds
 WHERE 
    shape IN ("round","princess","oval") 
 AND (carat BETWEEN ".1" AND "5") 
 AND (color BETWEEN "D" AND "Z") 
 AND (clarity_score BETWEEN "0" AND "10") 
 AND (cut_score BETWEEN "0" AND "5")

如您所见,我动态生成 clarity_scorecut_score 列,以便我可以在 WHERE 子句中使用它们。

首先,这给了我一个错误,告诉我 clarity_score 不存在。所以我想也许这是我需要使用 HAVING 的情况之一?

所以我将 where 子句更改为:

WHERE 
    shape IN ("round","princess","oval") 
 AND (carat BETWEEN ".1" AND "5") 
 AND (color BETWEEN "D" AND "Z") 
HAVING 
    (clarity_score BETWEEN "0" AND "10") 
 AND (cut_score BETWEEN "0" AND "5")

我没有错误,但结果为 0...这应该返回超过 100K。所以我在某个地方写错了?

然而,在开始重写之前,我不想选择这两个生成的字段,有没有办法可以编写它,这样我就不会检索这两个字段,而只是在 where 子句中使用它们?

I have this query:

SELECT diamond_id, carat, clarity, color, cut,
    CASE clarity
        WHEN "FL" THEN 0
        WHEN "IF" THEN 1
        WHEN "VVS1" THEN 2
        WHEN "VVS2" THEN 3
        WHEN "VS1" THEN 4
        WHEN "VS2" THEN 5
        WHEN "SI1" THEN 6
        WHEN "SI2" THEN 7
        WHEN "I1" THEN 8
        WHEN "I2" THEN 9
        WHEN "I3" THEN 10
        ELSE -1
    END AS clarity_score,
    CASE cut
        WHEN "ideal" THEN 0
        WHEN "excellent" THEN 1
        WHEN "very good" THEN 2
        WHEN "good" THEN 3
        WHEN "fair" THEN 4
        WHEN "poor" THEN 5
        ELSE -1
    END AS cut_score    
    FROM rapnet_diamonds
 WHERE 
    shape IN ("round","princess","oval") 
 AND (carat BETWEEN ".1" AND "5") 
 AND (color BETWEEN "D" AND "Z") 
 AND (clarity_score BETWEEN "0" AND "10") 
 AND (cut_score BETWEEN "0" AND "5")

As you can see I generate the clarity_score and cut_score columns on the fly so I can use them in my WHERE clause.

First of all, this is giving me an error telling me that clarity_score doesn't exist. SO I thought maybe this is one of those cases where I need to use HAVING instead?

so I changed my where clause to:

WHERE 
    shape IN ("round","princess","oval") 
 AND (carat BETWEEN ".1" AND "5") 
 AND (color BETWEEN "D" AND "Z") 
HAVING 
    (clarity_score BETWEEN "0" AND "10") 
 AND (cut_score BETWEEN "0" AND "5")

I got no error, but 0 results... This should be returning over 100K. So I wrote this wrong somewhere?

BEFORE YOU START rewriting this however, I DO NOT want to SELECT those 2 generated fields, is there a way I can write it so I am not retrieving those 2 fields, just using them in the where clause?

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

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

发布评论

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

评论(6

梦巷 2024-09-19 21:34:17

您可以执行以下操作。

创建两个查找表 向

create table clarity_lookup 
    (clarity_score int,
    clarity char(5))

create table cut_lookup 
    (cut_score int,
    cut char(10))

查找表加载数据

INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (0, 'FL')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (1, 'IF')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (2, 'VVS1')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (3, 'VVS2')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (4, 'VS1')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (5, 'VS2')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (6, 'SI1')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (7, 'SI2')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (8, 'I1')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (9, 'I2')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (10, 'I3')

INSERT INTO cut_lookup (cut_score, cut) VALUES (0, 'ideal')
INSERT INTO cut_lookup (cut_score, cut) VALUES (1, 'excellent')
INSERT INTO cut_lookup (cut_score, cut) VALUES (2, 'very good')
INSERT INTO cut_lookup (cut_score, cut) VALUES (3, 'good')
INSERT INTO cut_lookup (cut_score, cut) VALUES (4, 'fair')
INSERT INTO cut_lookup (cut_score, cut) VALUES (5, 'poor')

您的查询将如下所示。总之,您将根据分数将表示原始 CASE 子句中的数据的新表连接到 Diamonds 表,但在 SELECT 子句中显示说明。

SELECT rapnet_diamonds.diamond_id, rapnet_diamonds.carat,
    clarity_lookup.clarity, rapnet_diamonds.color, cut_lookup.cut
FROM rapnet_diamonds
LEFT OUTER JOIN clarity_lookup ON rapnet_diamonds.clarity_score = clarity_lookup.clarity_score
LEFT OUTER JOIN cut_lookup ON rapnet_diamonds.cut_score = cut_lookup.cut_score
WHERE rapnet_diamonds.shape IN ('round','princess','oval') 
    AND (rapnet_diamonds.carat BETWEEN .1 AND 5) 
    AND (rapnet_diamonds.color BETWEEN 'D' AND 'Z') 
    AND (rapnet_diamonds.clarity_score BETWEEN 0 AND 10) 
    AND (rapnet_diamonds.cut_score BETWEEN 0 AND 5)

You can do the following.

Create two look-up tables

create table clarity_lookup 
    (clarity_score int,
    clarity char(5))

create table cut_lookup 
    (cut_score int,
    cut char(10))

Load the look-up tables with data

INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (0, 'FL')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (1, 'IF')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (2, 'VVS1')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (3, 'VVS2')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (4, 'VS1')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (5, 'VS2')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (6, 'SI1')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (7, 'SI2')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (8, 'I1')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (9, 'I2')
INSERT INTO clarity_lookup (clarity_score, clarity) VALUES (10, 'I3')

INSERT INTO cut_lookup (cut_score, cut) VALUES (0, 'ideal')
INSERT INTO cut_lookup (cut_score, cut) VALUES (1, 'excellent')
INSERT INTO cut_lookup (cut_score, cut) VALUES (2, 'very good')
INSERT INTO cut_lookup (cut_score, cut) VALUES (3, 'good')
INSERT INTO cut_lookup (cut_score, cut) VALUES (4, 'fair')
INSERT INTO cut_lookup (cut_score, cut) VALUES (5, 'poor')

Your query would look like the following. In summary, you would join your new tables, which represent the data in your original CASE clauses, to the diamonds table based on the scores, but display the descriptions in your SELECT clause.

SELECT rapnet_diamonds.diamond_id, rapnet_diamonds.carat,
    clarity_lookup.clarity, rapnet_diamonds.color, cut_lookup.cut
FROM rapnet_diamonds
LEFT OUTER JOIN clarity_lookup ON rapnet_diamonds.clarity_score = clarity_lookup.clarity_score
LEFT OUTER JOIN cut_lookup ON rapnet_diamonds.cut_score = cut_lookup.cut_score
WHERE rapnet_diamonds.shape IN ('round','princess','oval') 
    AND (rapnet_diamonds.carat BETWEEN .1 AND 5) 
    AND (rapnet_diamonds.color BETWEEN 'D' AND 'Z') 
    AND (rapnet_diamonds.clarity_score BETWEEN 0 AND 10) 
    AND (rapnet_diamonds.cut_score BETWEEN 0 AND 5)
情绪失控 2024-09-19 21:34:17

这行不通吗? (我对 MySQL 的经验有限。)

SELECT diamond_id, carat, clarity, color, cut
  FROM rapnet_diamonds
 WHERE 
    shape IN ("round","princess","oval") 
 AND (carat BETWEEN ".1" AND "5") 
 AND (color BETWEEN "D" AND "Z") 
 AND (  CASE clarity
        WHEN "FL" THEN 0
        WHEN "IF" THEN 1
        WHEN "VVS1" THEN 2
        WHEN "VVS2" THEN 3
        WHEN "VS1" THEN 4
        WHEN "VS2" THEN 5
        WHEN "SI1" THEN 6
        WHEN "SI2" THEN 7
        WHEN "I1" THEN 8
        WHEN "I2" THEN 9
        WHEN "I3" THEN 10
        ELSE -1
    END BETWEEN "0" AND "10") 
 AND (  CASE cut
        WHEN "ideal" THEN 0
        WHEN "excellent" THEN 1
        WHEN "very good" THEN 2
        WHEN "good" THEN 3
        WHEN "fair" THEN 4
        WHEN "poor" THEN 5
        ELSE -1
    END BETWEEN "0" AND "5")

Doesn't this work? (I have limited experience with MySQL.)

SELECT diamond_id, carat, clarity, color, cut
  FROM rapnet_diamonds
 WHERE 
    shape IN ("round","princess","oval") 
 AND (carat BETWEEN ".1" AND "5") 
 AND (color BETWEEN "D" AND "Z") 
 AND (  CASE clarity
        WHEN "FL" THEN 0
        WHEN "IF" THEN 1
        WHEN "VVS1" THEN 2
        WHEN "VVS2" THEN 3
        WHEN "VS1" THEN 4
        WHEN "VS2" THEN 5
        WHEN "SI1" THEN 6
        WHEN "SI2" THEN 7
        WHEN "I1" THEN 8
        WHEN "I2" THEN 9
        WHEN "I3" THEN 10
        ELSE -1
    END BETWEEN "0" AND "10") 
 AND (  CASE cut
        WHEN "ideal" THEN 0
        WHEN "excellent" THEN 1
        WHEN "very good" THEN 2
        WHEN "good" THEN 3
        WHEN "fair" THEN 4
        WHEN "poor" THEN 5
        ELSE -1
    END BETWEEN "0" AND "5")
旧时浪漫 2024-09-19 21:34:17

我会将 case 语句逻辑放入查找解码器表中,然后加入其中。
然后你可以使用where子句中的列,它简化了SQL。

类似的东西

create table ClarityCode
(
   Clarity char(x) not null
,  CodeID int not null
)

I would put the case statement logic into a look up decoder table, and join to that.
Then you can use the columns in the where clause, and it simplifies the SQL.

something like

create table ClarityCode
(
   Clarity char(x) not null
,  CodeID int not null
)
杀お生予夺 2024-09-19 21:34:17

为什么不使用IN?

SELECT diamond_id, carat, clarity, color, cut
FROM rapnet_diamonds
WHERE
shape IN ("round","princess","oval") AND
(carat BETWEEN ".1" AND "5") AND
(color BETWEEN "D" AND "Z") AND
clarity IN ('FL', 'IF', 'VVS1', 'VVS2', 'VS1', 'VS2', 'SI1', 'SI2', 'I1', 'I2', 'I3') AND
cut IN ('ideal', 'excellent', 'very good', 'good', 'fair', 'poor')

why not use IN?

SELECT diamond_id, carat, clarity, color, cut
FROM rapnet_diamonds
WHERE
shape IN ("round","princess","oval") AND
(carat BETWEEN ".1" AND "5") AND
(color BETWEEN "D" AND "Z") AND
clarity IN ('FL', 'IF', 'VVS1', 'VVS2', 'VS1', 'VS2', 'SI1', 'SI2', 'I1', 'I2', 'I3') AND
cut IN ('ideal', 'excellent', 'very good', 'good', 'fair', 'poor')
花之痕靓丽 2024-09-19 21:34:17

我会接受您的查询并稍微修改您的代码以使其工作

SELECT * FROM 
  (
    SELECT diamond_id, carat, clarity, color, cut, 
        CASE clarity 
            WHEN "FL" THEN 0 
            WHEN "IF" THEN 1 
            WHEN "VVS1" THEN 2 
            WHEN "VVS2" THEN 3 
            WHEN "VS1" THEN 4 
            WHEN "VS2" THEN 5 
            WHEN "SI1" THEN 6 
            WHEN "SI2" THEN 7 
            WHEN "I1" THEN 8 
            WHEN "I2" THEN 9 
            WHEN "I3" THEN 10 
            ELSE -1 
        END AS clarity_score, 
        CASE cut 
            WHEN "ideal" THEN 0 
            WHEN "excellent" THEN 1 
            WHEN "very good" THEN 2 
            WHEN "good" THEN 3 
            WHEN "fair" THEN 4 
            WHEN "poor" THEN 5 
            ELSE -1 
        END AS cut_score     
        FROM rapnet_diamonds 
     WHERE  
        shape IN ("round","princess","oval")  
     AND (carat BETWEEN ".1" AND "5")  
     AND (color BETWEEN "D" AND "Z")
)t 
WHERE   
     (clarity_score BETWEEN "0" AND "10")  
     AND (cut_score BETWEEN "0" AND "5") 

您不能在 where 子句中使用 Case 变量

I would take your query and modify you code little bit to get it work

SELECT * FROM 
  (
    SELECT diamond_id, carat, clarity, color, cut, 
        CASE clarity 
            WHEN "FL" THEN 0 
            WHEN "IF" THEN 1 
            WHEN "VVS1" THEN 2 
            WHEN "VVS2" THEN 3 
            WHEN "VS1" THEN 4 
            WHEN "VS2" THEN 5 
            WHEN "SI1" THEN 6 
            WHEN "SI2" THEN 7 
            WHEN "I1" THEN 8 
            WHEN "I2" THEN 9 
            WHEN "I3" THEN 10 
            ELSE -1 
        END AS clarity_score, 
        CASE cut 
            WHEN "ideal" THEN 0 
            WHEN "excellent" THEN 1 
            WHEN "very good" THEN 2 
            WHEN "good" THEN 3 
            WHEN "fair" THEN 4 
            WHEN "poor" THEN 5 
            ELSE -1 
        END AS cut_score     
        FROM rapnet_diamonds 
     WHERE  
        shape IN ("round","princess","oval")  
     AND (carat BETWEEN ".1" AND "5")  
     AND (color BETWEEN "D" AND "Z")
)t 
WHERE   
     (clarity_score BETWEEN "0" AND "10")  
     AND (cut_score BETWEEN "0" AND "5") 

You cannot use Case variables in where clause

自此以后,行同陌路 2024-09-19 21:34:17

为了满足对拆分表想法进行更多解释的愿望:

您无需将所有内容都放在 CASE 语句中,而是将清晰度信息存储在第二个表中。它可能看起来像这样:

Clarity_Table
-----------------------
Clarity_score | clarity
-----------------------
0             | FL
1             | IF
2             | VVS1
3             | VVS2
4             | VS1
5             | VS2
...
10            | I3

Cut_Table 也是如此,希望您从上面得到了这个想法。

然后,将查询更改为:

SELECT diamond_id, carat, clarity, color, cut, clarity_score, cut_score    
    FROM rapnet_diamonds JOIN clarity_table USING(clarity)
                         JOIN cut_table USING(cut)
 WHERE 
    shape IN ("round","princess","oval") 
 AND (carat BETWEEN ".1" AND "5") 
 AND (color BETWEEN "D" AND "Z") 
 AND (clarity_score BETWEEN "0" AND "10") 
 AND (cut_score BETWEEN "0" AND "5")

然后,它不会对分数进行硬编码,而是在表之间进行联接。我怀疑它会经常更新,但它会让以后的更改变得更容易,并且使整体代码维护和维护变得容易。可读性更容易。

In response to the desire for more explanation for the split-table idea:

Rather than having everything in a CASE statement, you store the clarity information in a second table. It might look something like this:

Clarity_Table
-----------------------
Clarity_score | clarity
-----------------------
0             | FL
1             | IF
2             | VVS1
3             | VVS2
4             | VS1
5             | VS2
...
10            | I3

And the same thing for Cut_Table, hopefully you get the idea from above.

then, change your query to:

SELECT diamond_id, carat, clarity, color, cut, clarity_score, cut_score    
    FROM rapnet_diamonds JOIN clarity_table USING(clarity)
                         JOIN cut_table USING(cut)
 WHERE 
    shape IN ("round","princess","oval") 
 AND (carat BETWEEN ".1" AND "5") 
 AND (color BETWEEN "D" AND "Z") 
 AND (clarity_score BETWEEN "0" AND "10") 
 AND (cut_score BETWEEN "0" AND "5")

Then, rather than hard-coding the scores, it does a join between the tables. I doubt it will get updated very often, but it would make changing things later easier, and makes overall code maintenance & readability MUCH easier.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文