我有两张桌子要加入。
表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.在表2中,应选择在给定日期范围内的所有列和行。 / p>
我想知道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来轻松解决整个问题,并避免使用JOIN
和2 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
答案 0 :(得分:1)
问:我想知道WHERE子句是否应该出现在我上面的CROSS JOIN子句之后。
答:是的,这是WHERE
子句的正确位置。
问:我是否应该删除第二个WHERE关键字,而是使用以下命令。
答:是的,WHERE
子句只能在简单的SELECT
语句中出现一次。每个子查询都有自己的WHERE
子句,但每个SELECT实际上仍然只有一个WHERE
子句。
问:我的第三个问题是棘手的问题。可以在这样的单个命令中使用2个不同的WHERE子句,但是可以应用于单独的表吗?当我加入表时,我可以使用WHERE Table1(条件)和WHERE Table2(条件)吗?
答: WHERE
关键字每SELECT
只能出现一次。您可以在任何表格中包含谓词。
另外,要回答一些您没有问过的其他问题......
您需要在ORDER BY
子句中提供表达式或表达式列表。默认顺序为ASC
,因此最常省略此关键字。
Table2的Date列上的谓词似乎表示日期文字。 (正如它们在你的陈述中,它们似乎代表一个整数值,由一系列除法运算得出。
应该将文字显式转换为DATETIME(以匹配Date列的数据类型)。 SQL Server不需要显式的CONVERT,但如果没有转换,您确实希望这些转换为规范(明确)格式的字符串。 ('3/5/2012'代表3月5日,还是5月3日?)
SQL Server DATTIME数据类型存储日期和时间组件。通常,当用户要求结束日期时,它们也意味着当天的任何时间。考虑到'2011-12-30 09:30:00'的DATETIME值不是&lt; ='2011-12-30',我们通常会编写一个小于第二天午夜的测试。< / p>
将列引用限定为非常好的做法。这通常使用表别名来完成。表别名不是必需的,但它们是熟悉的模式,可以使读取语句更容易。当表名完全限定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比较将产生不良结果。
(注意到字符串'3/5/2011'不在'2011年1月1日'和'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)
答案 1 :(得分: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
答案 2 :(得分: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
类型的日期匹配。