【问题标题】:SQL: How to create two columns from same data source based on conditions?SQL:如何根据条件从同一数据源创建两列?
【发布时间】:2016-11-09 19:16:29
【问题描述】:

刚开始学习SQL,正在网上做一些练习题。 我在这里遇到了这个问题(页面上的#11):http://sqlzoo.net/wiki/AdventureWorks_hard_questions

这是我们将用于解决此问题的 3 个表的架构:

CustomerAW(CustomerID、FirstName、MiddleName、LastName、CompanyName、EmailAddress)

客户地址(客户 ID、地址 ID、地址类型)

地址(AddressID、AddressLine1、AddressLine2、City、StateProvince、CountyRegion、PostalCode)

问题是:

对于在达拉斯拥有“主办公室”的每位客户,请显示“主办公室”的 AddressLine1 和“送货”地址的 AddressLine1 - 如果没有送货地址,请将其留空。每位客户使用一行。

下面是我的代码:

SELECT CustomerID, AddressType,  AddressLine1
FROM CustomerAW
JOIN CustomerAddress
USING (CustomerID)
JOIN Address
USING (AddressID)
WHERE AddressType IN 'Main Office'
AND  City = 'Dallas'
;

下面是我得到的输出:

Result:
CustomerID  AddressType AddressLine1
112         Main Office P.O. Box 6256916
130         Main Office Po Box 8259024
165         Main Office 2500 North Stemmons Freeway
201         Main Office Po Box 8035996
256         Main Office 99828 Routh Street, Suite 825.

但我不知道如何在单独的列中显示送货地址。 这样标题就变成了 “CustomerID、AddressType、MainOfficeAddress、ShippingAddress”。如问题所述,如果没有送货地址,请留空。

更新

如何在不使用“视图”的情况下做到这一点?我正在测试的网站不允许我创建视图...

我尝试过的

嗯,我尝试了不同的方法来实现这一点,其中一种是在 SELECT 语句中编写子查询:

SELECT c.CustomerID,  
(
SELECT a.AddressLine1 FROM Address a
JOIN CustomerAddress ca
USING (AddressID)
WHERE ca.AddressType = 'Main Office'
) AS MainOfficeAddress
FROM CustomerAW c
;

然后我会收到错误消息“子查询返回超过 1 行”。

我也尝试过类似下面的方法(实际上都没有工作):

SELECT c.CustomerID,  b.AddressLine1, e.AddressLine1
FROM CustomerAW c
JOIN
(
SELECT * FROM CustomerAddress ca
JOIN Address a
USING (AddressID)
WHERE ca.AddressType IN 'Main Office'
) AS b
USING (CustomerID)
JOIN
(
SELECT * FROM CustomerAddress ca
JOIN Address a
USING (AddressID)
WHERE ca.AddressType IN 'Shipping'
) AS e
USING (CustomerID)
;

还有:

SELECT c.CustomerID, AddressType,  AddressLine1 AS MainOfficeAddress, 
(
    SELECT a.AddressLine1 FROM Address a
    JOIN CustomerAddress ca USING (AddressID)
    WHERE ca.CustomerID IN c.CustomerID
    AND ca.AddressType = 'Shipping'
) AS ShippingAddress
FROM CustomerAW c
JOIN CustomerAddress ca
USING (CustomerID)
JOIN Address
USING (AddressID)
WHERE ca.AddressType IN ('Main Office')
AND City = 'Dallas'
;

非常感谢任何帮助!希望我不是在问一个愚蠢的问题。

【问题讨论】:

    标签: mysql


    【解决方案1】:

    您应该使用“内部连接”。 编写与上面相同的代码,为简单起见创建一个视图,我的意思是

    create view ee as
    (
        SELECT CustomerID, AddressType,  AddressLine1
        FROM CustomerAW
        JOIN CustomerAddress
        USING (CustomerID)
        JOIN Address
        USING (AddressID)
        WHERE AddressType IN 'Main Office'
        AND  City = 'Dallas'
     )   ;
    

    然后写..

        create view rr as
        (
        SELECT CustomerID, AddressType,  AddressLine1
        FROM CustomerAW
        JOIN CustomerAddress
        USING (CustomerID)
        JOIN Address
        USING (AddressID)
        WHERE AddressType IN 'Shipping Address'
        );
    

    然后取视图 ee 和 rr 的内连接

    select CustomerID, AddressType, MainOfficeAddress, ShippingAddress
    from ee
    inner join
    rr
    on ee.customerID=rr.CustomerID
    

    希望这有帮助.... ;)

    【讨论】:

    • 您好 Tanuj,非常感谢您的回答!请问您如何使用“视图”来实现这一点?另外...第一次听到使用“视图”,您可以扩展一下视图是什么吗?我认为 view 更多的是让您“查看”表格,而不是在查询中使用...
    • 视图是一个虚拟表,它指的是一个真实的表。它存储一些数据。一旦声明了视图,就可以像使用表格一样使用它。
    • 我明白了。所以不是创建一个新表或使用子查询,而是在这里使用视图。并且视图只是暂时存储在内存中,下次拉取时就无法使用了。我理解正确吗?
    • 是的,你说得对。您甚至可以通过视图更新表格。我的意思是,如果您对视图进行更改,这些更改也会反映在表中,但前提是视图仅引用单个表而不是多个表。如果有帮助,请为答案投票。
    • 嗨 Tanuj,所以您是说表值实际上可以通过视图永久修改?此外,我不断收到错误“CREATE VIEW command denied to user 'scott'@'localhost' for table 'ee'”。绝对赞成你的回答。非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-29
    • 1970-01-01
    相关资源
    最近更新 更多