选择列时,SQL连接在where子句之前?

时间:2015-07-03 13:48:52

标签: sql sql-server join

这有点奇怪。这个特殊的糟糕的数据库设计让我感到很多次,而且我总是不得不做出荒谬的工作,这也不例外。总结一下:我有3个表,第一个是问题查找表,第二个是答案查找表,第三个存储问题和答案ID以显示已回答哪些问题。到目前为止直截了当。

然而答案可以是3种类型中的1种:自由文本,多项选择或多项选择,这些都存储在同一列中(答案)。自由文本可以是任何内容,例如' Hello'或者约会时间2015-07-03 00:00:00'多项选择存储为整数1或49等,多项选择存储为分隔字符串' 1,4,7,8' (我知道这是一个非常糟糕的设计,专栏不应该存储超过1个值但是它在我的时间之前并写入我们的aspx Web应用程序,因为我自己工作我根本没有资源或时间改变它)

问题出现了;看看这个查询:

Select *
FROM AnswersTable
JOIN LK_Questions
ON AnswersTable.QuestionID = LK_Questions.QuestionID
JOIN LK_Answers
ON AnswersTable.Answer = LK_Answers.AnswerID
Where LK_Questions.QuestionTypeID = 1

where子句应该确保返回的唯一问题是多项选择。 (所以我没有加入一个整数的自由文本答案)并且实际上当我运行此查询时它运行正常,但是当我尝试选择单个列时,它会出错并显示以下错误消息:

  

转换varchar值时转换失败',879'数据类型smallint。

它几乎喜欢在它之前进行连接,尽管我知道查询优化器不会那样工作。问题是我需要选择列名,因为这是进入一个表,所以我需要定义列名。有什么我可以做的吗?我已经尝试了很长时间但没有结果。我应该提一下,我正在运行SQL Server 2005。

非常感谢提前

编辑:

这是导致错误的查询:

Select LK_Answers.Answer
FROM AnswersTable
JOIN LK_Questions
ON AnswersTable.QuestionID = LK_Questions.QuestionID
JOIN LK_Answers
ON AnswersTable.Answer = LK_Answers.AnswerID
Where LK_Questions.QuestionTypeID = 1

4 个答案:

答案 0 :(得分:0)

您可以使用子选择。

Select *
FROM AnswersTable
JOIN ( SELECT * FROM LK_Questions Where QuestionTypeID = 1) as LK_Questions
    ON AnswersTable.QuestionID = LK_Questions.QuestionID
JOIN LK_Answers
    ON AnswersTable.Answer = LK_Answers.AnswerID

答案 1 :(得分:0)

您正在根据答案表的答案字段加入查找表的ID字段。这样好吗?

答案 2 :(得分:0)

注意那些领域;

AnswersTable.QuestionID, LK_Questions.QuestionID
AnswersTable.Answer , LK_Answers.AnswerID and LK_Questions.QuestionTypeID 

他们共享相同的数据类型吗?

如果是这样,您应该更改您的查询;

     SELECT * FROM AnswersTable RIGHT JOIN LK_Questions ON LK_Questions.QuestionTypeID = AnswersTable.QuestionID JOIN LK_Answers ON AnswersTable.Answer = LK_Answers.AnswerID where LK_Questions.QuestionTypeID = 1   

答案 3 :(得分:0)

您的查询中的问题是,您用于将表连接在一起的列上的数据类型不匹配。

解决此问题的最简单方法之一是明确CAST联接的两侧到VARCHAR,以便在加入时匹配数据类型没有问题。这并不理想,但是如果您无法更改表架构,那么您必须解决它。

SQL Fiddle Demo

CREATE TABLE LeftTable
(
  id INT
);

CREATE TABLE RightTable
(
  id VARCHAR(30)
);

INSERT INTO LeftTable (id)
VALUES (1), (2), (3), (4), (5);

INSERT INTO RightTable (id)
VALUES ('1'), ('2'), ('3'), ('4'), ('5'), (',879');

SELECT l.*, r.*
FROM LeftTable l
JOIN RightTable r ON CAST(l.id AS VARCHAR(30)) = CAST(r.id AS VARCHAR(30))
WHERE l.id = '1'