2012-06-22 55 views
0

我有两个表,我想将它们连接在一起。SQL命令可以在同一命令行中使用,但可以在两个不同的表上使用

表1

Year, ID, Theme, 

表2

First, Last, WeekID, Date, Affiliation 

我想用这个命令

SELECT * 
FROM Table1 
CROSS JOIN Table2 
WHERE Table1.ID = 5 
    AND WHERE Table2.Date >= 1/1/2011 
    AND Table2.Date <= 12/30/2011 
ORDER BY Asc 

我想做的发生是所有的行和列从表1是选择ID列包含int值为5的位置。在Table2中,应该选择所有列和行都在给定日期范围内。

我想知道WHERE子句是否应该在CROSS JOIN子句之后,如上所述。另外,我应该删除第二个WHERE关键字,而不是有以下命令。

SELECT * 
FROM Table1 
CROSS JOIN Table2 
WHERE Table1.ID = 5 
    AND Table2.Date >= 1/1/2011 
    AND Table2.Date <= 12/30/2011 
ORDER BY Asc 

我的第三个问题是很棘手的。可以将2个不同的WHERE子句用于像这样的单个命令,但是可以应用于单独的表?当我加入表格时,我可以有WHERE Table1 (*Condition*) AND WHERE Table2 (*Condition*)吗?

我想我可以通过为每个表创建2个单独的SQL命令1并避免使用JOIN2 WHERE子句来轻松解决整个问题。这是你会推荐的吗?

最终的结果会是这个样子

表3

ID, Year, Theme, WeekID, Date, First, Last, Affiliation 

随后的细胞是为了在根据日期按升序排列。

一个示例表低于

表3

ID  Year  Theme  WeekID  Date   First  Last Affiliation 
5  2011  Stuff1 1   01/09/2011 Foo  Bar  Baz Inc 
5  2011  Stuff2 2   01/14/2011 Flum  Baz  Bar Inc 
5  2011  Stuff3 3   04/15/2011 Bar  Flum Bub Inc 
5  2011  Stuff4 4   05/01/2011 Bar  Foo  FlumBub Inc 
5  2011  Stuff5 5   08/16/2011 Bub  Baz  Foo Inc 
+1

如何在这些2个表有关?没有加入条件... – Randy

+2

@Randy:我想这就是为什么Derek正在使用CROSS JOIN。 –

+0

CROSS JOIN子句应该与它们相关 – TheDude

回答

1

问:我想知道WHERE子句是否应该在CROSS JOIN子句之后,如上所述。

A:是的,这是WHERE条款的正确位置。

问:也应该删除第二个WHERE关键字,而不是有以下命令。

A:是的,WHERE子句只能在简单的SELECT语句中出现一次。每个子查询可以有它自己的WHERE子句,但这实际上仍然是每个SELECT一个WHERE子句。

问:我的第三个问题是棘手的问题。在这样的单个命令中是否可以使用2个不同的WHERE子句,但是可以应用于单独的表?意思我可以在哪里表1(条件)和哪里表2(条件)当我加入表?

A:WHERE关键字只能出现一次,每SELECT。你可以在任何表格中包含谓词。


另外,回答你也没问一些额外的问题...

您需要提供一个表达式,或者表达式的列表中,ORDER BY子句。默认顺序是ASC,所以此关键字最常被忽略。

Table2的Date列上的谓词看起来代表日期文字。 (因为它们在你的语句中,它们看起来代表一个整数值,由一系列除法运算得出)

文字应该明确地转换为DATETIME(以匹配Date列的数据类型)显式CONVERT不是SQL Server所需要的,但是如果没有转换,你真的希望那些被表示为规范的(明确的)格式的字符串。('3/5/2012'代表3月5日还是5月3日?)

SQL Server DATTIME数据类型存储日期和时间组件,通常,当用户要求结束日期时,它们也意味着当天的任何时间。 :30:00'不是< ='2011-12-30',我们通常会编写一个LESS THAN中期测试第二天晚上。

这是非常好的做法来限定对列的引用。这通常使用表别名来完成。表别名不是必需的,但它们是一个熟悉的模式,并且可以使阅读语句更容易。当表名完全限定为mydatabase.schema.MyLongAndUnWeILDyTblName时尤其如此,并且在更复杂的表达式中使用的完全限定列名可以使表达式解密非常乏味。 (在你的情况下,这不是一个真正的问题,但它是我们遵循的模式,即使是简单的陈述。)

此外,最佳做法是避免在SELECT列表中使用*(除非您从内联视图或CTE在声明中)。而是列出您想要返回的特定表达式。对于测试和开发,使用*很好。除了那些小问题,你的陈述看起来很好。 (避免*和限定列名避免未来可能发生的问题,例如,当一个新列被添加到一个表中时,会引起一个前面没有的“模糊列”异常。 (我们希望能够增加一列没有应用程序运行的每一个SQL语句的完整回归测试。)

鉴于所有这些信息,你没有问...在我们的商店,该语句来回报您指定结果集将被格式化是这样的:

SELECT t1.ID 
    , t1.Year 
    , t1.Theme 
    , t2.WeekID 
    , t2.Date 
    , t2.First 
    , t2.Last 
    , t2.Affiliation 
    FROM dbo.Table1 t1 
CROSS 
    JOIN dbo.Table2 t2 
WHERE t1.ID = 5 
    AND t2.Date >= CONVERT(DATETIME,'2011-01-01',20) 
    AND t2.Date < CONVERT(DATETIME,'2011-12-31',20) 
ORDER 
    BY t1.ID 
    , t1.Year 
    , t1.Theme 
    , t2.WeekID 
    , t2.Date 
    , t2.First 
    , t2.Last 
    , t2.Affiliation 

在后面的评论中,Derek指出Date列是VARCHAR。在这种情况下,不幸的,我们需要知道的日期在。

呈现的格式。如果字符串表示不在一个规范格式的VARCHAR比较会产生不良的结果。

(注意该字符串“2011年3月5日”之间没有“2011/1/1” AND '12/30/2011' )。

有显著的优势使用DATETIME数据类型存储日期值。如果这是不可能的(无论何种原因阴险有人来了),和字符串不是一个规范的格式,则谓词确实应该更多的东西一样:

AND CONVERT(DATETIME,t2.Date,101) >= CONVERT(DATETIME,'01/01/2011',101) 
AND CONVERT(DATETIME,t2.Date,101) < CONVERT(DATETIME,'12/31/2011',101) 
+0

我已请求更新SQL数据库,以便日期列不再是varchar,而不是类型日期。这完全只是测试和试验单个SQL命令代码可以做什么。我们遇到了一个实例,在这个实例中,我们遇到了一个说SQL命令很长的错误。我可以;不记得它给我们的确切的#,但由于某种原因,我的头上有128根棍子。 – TheDude

+0

@ Derek- SQL Server语句的最大大小SQLText非常大。在64位系统上,我相信它在2GB左右。在打击查询文本的SQL Server最大大小之前,您将遇到其他限制。 – spencer7593

0

我想你最好是去使用CTE这样的:

WITH Table1CTE (COL1, COL2) 
AS 
(
SELECT COL1, COL2 
FROM Table1 
WHERE Table1.ID = 5 
), 
Table2CTE (COL3, COL4) 
AS 
(
SELECT COL3, COL4 
FROM TABLE2 
WHERE Table2.Date >= 1/1/2011 
    AND Table2.Date <= 12/30/2011 
) 
SELECT * 
FROM Table1CTE CROSS JOIN Table2CTE 
ORDER BY COL1 ASC 
+0

你能不能给我一个简要的解释,究竟这是应该做? – TheDude

+0

刚刚注意到您对日期的评论 - 您可能需要为该部分执行Cast(Table2.Date as DateTime)> = 2011/1/1。 – CompuChip

+0

就CTE所做的而言,CTE中的每个查询都只返回该表所需的记录。如果您在每个CTE上执行交叉连接,它应该为您提供交叉连接所需的记录。对于CTE的一个很好的资源,请查看http://www.4guysfromrolla.com/webtech/071906-1.shtml – CompuChip

0

第一SELECT命令

SELECT * 
FROM Table1 
CROSS JOIN Table2 
WHERE Table1.ID = 5 
    AND WHERE Table2.Date >= 1/1/2011 
    AND Table2.Date <= 12/30/2011 
ORDER BY Asc 

将产生近WHERE关键字

只有一个WHERE语句需要使用可以通过AND指定的任何其他条件的

不正确的语法错误。

而且上述需要指定的日期被格式化为例如

Table2.Date >= '01/01/2011' AND Table2.Date <= '12/30/2011' 

否则SQL命令将执行整数运算和类型转换为int,而不是匹配日期字符串,其在表中的日期类型varchar

+1

,为什么你的日期列varchar? –

+0

因为我没有设置我刚刚使用它们的SQL表。我已要求将其更改为键入日期。无论哪种方式日期ot varchar要求日期边界被撇号围起来 – TheDude

+0

在初始'WHERE'之后,通过简单的'AND'而不是'AND WHERE ....'来添加附加条件。在有效的SQL语句中不能有多个WHERE –

相关问题