1

这是一个来自真实世界 SQL 应用程序问题的示例。我是 SQL 的新用户。

设计一个 (SQL)SELECT语句,返回居住在密歇根州的所有非测试帐户的名称列表,并包括它返回的内容。

Table: CustomerAcct_tab 

  id    first_name  last_name   address_id  account_type_code
 234    John        Smith       123         A
 342    Mary        Ryan        223         C
 210    Mark        Jackson     398         B
 678    Bill        Monroe      232         C
 789    JoAnne      Hill        300         D

 Table: Address_tab 

  id    State   
 123    MI  
 223    TX  
 398    CA  
 232    MI  
 300    CA  

 Table: AccountType_tab 

 code   is_test_account 
   A    TRUE    
   B    FALSE   
   C    FALSE   
   D    TRUE    

我的解决方案:

SELECT first_name, Last_name
FROM CustomerAcct_tab
INNER JOIN Address_tab ON CustomerAcct_tab.address_id = Address_tab.id 
INNER JOIN AccountType_tab ON CustomerAcct_tab.account_type_code = AccountType_tab.code 
WHERE is_test_account = FALSE AND Address_tab.State = MI

但是,我认为这可能不正确。

我的同事建议我需要为 CustomerAcct_tab 创建一些索引,否则它是错误的,但我不知道如何以及为什么。

4

2 回答 2

1

如果您询问如何以及在何处创建适合此查询的索引,我建议:

create index Address_tab_State_index on Address_tab(State);
create index CustomerAcct_tab_address_id_index CustomerAcct_tab(address_id);

并重构查询以按对这些索引最有利的顺序选择表:

SELECT first_name, Last_name
FROM Address_tab
JOIN CustomerAcct_tab ON CustomerAcct_tab.address_id = Address_tab.id
JOIN AccountType_tab 
    ON CustomerAcct_tab.account_type_code = AccountType_tab.code 
    AND is_test_account = FALSE
WHERE Address_tab.State = MI

此查询在执行期间尽可能早地过滤掉不匹配的行,从而加入来自后续表的最少行数。

请注意is_test_account = FALSEON子句中而不是在WHERE子句中使用条件,从而减少一点执行开销(避免在连接结果中进行过滤)。

另请注意,您可能已经定义了一个索引,CustomerAcct_tab(address_id)因为它是一个外键列。

于 2012-05-18T01:21:01.337 回答
-1

如果我正确理解您的问题,您的同事指出的问题是 account_type 代码应该是数字而不是字符或字符串。尽管可以将字符串索引为外键,但这并不常见。
这是正确的查询:

SELECT first_name, Last_name FROM CustomerAcct_tab

INNER JOIN Address_tab ON CustomerAcct_tab.address_id = Address_tab.id

INNER JOIN AccountType_tab ON CustomerAcct_tab.account_type_code = AccountType_tab.code

WHERE AccountType_tab.code <> 'A' AND Address_tab.State = MI
于 2012-05-18T00:47:57.687 回答