从一个表或另一个表中选择列

时间:2013-02-07 02:42:53

标签: mysql

说我有两张桌子:

CREATE TABLE state (
    id TINYINT,
    state CHAR(2),
    PRIMARY KEY (id)
);

CREATE TABLE valid_state (
    id INT,
    state CHAR(2), # or stateId TINYINT or whatever
    productId INT
);

如果产品只能在CA销售,则在valid_state中只有一个条目。如果它可以在所有州出售,则valid_state中不会有任何条目。如果无法在任何状态下销售,则需要在未定义的产品表中禁用该产品。

我的问题是:如何选择给定产品的所有有效状态?理想情况下,我想从valid_state中选择,看看它是否为空,如果是,则返回所有状态。不幸的是,我不知道该怎么做。

有什么想法吗?

(另外,fwiw,我没有设计架构所以建议我改变它没有那么有帮助)

2 个答案:

答案 0 :(得分:1)

您可以使用UNIONNOT EXISTS

来实现此目的
SELECT DISTINCT S.Id, 
   S.State
FROM State S
   JOIN valid_state V ON S.State = V.State AND V.ProductId = @ProductId
UNION 
SELECT DISTINCT S.Id, 
   S.State
FROM State S
WHERE NOT EXISTS  (SELECT * FROM valid_state WHERE ProductId = @ProductId)

以下是示例Fiddle

祝你好运。

答案 1 :(得分:0)

我想出了一个不同的方法。

我得到所有状态,并标记哪一个对第一个LEFT JOIN的给定产品有效。

使用第二个LEFT JOIN,我将产品有效的所有状态和连接在一起。如果没有V.id = V2.id我会返回valid_states * 2行但是有了它我只有我想要的那些。

SELECT S.Id, S.State
FROM state S
LEFT JOIN valid_state V
  ON V.state = S.state
    AND productId = @ProductId
LEFT JOIN (state S2, valid_state V2)
    ON V2.productId = @ProductId
        AND S2.state = S.state
WHERE V.id = V2.id OR V2.id IS NULL;

我不知道哪一个更好。 EXPLAIN for sgeddes显示它正在查看3 * 3 * 3行,而我的正在做3 * 3 * 3 * 3。但是sgeddes在EXPLAIN中有五列(其中两列对于行为NULL)并且是“使用临时”,“使用连接缓冲区”并且具有“不可能的WHERE”

有什么想法吗?