0

我有两张表要连接在一起。

表格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 中,应选择给定日期范围内的所有列和行。

我想知道该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*)当我加入表格时,我可以有什么意思?

JOIN我想我可以通过为每个表创建 2 个单独的 SQL 命令 1 并避免使用and2 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 
4

3 回答 3

1

问:我想知道 WHERE 子句是否应该像我上面所说的那样在 CROSS JOIN 子句之后。

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

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

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

问:我的第三个问题比较棘手。可以在这样的单个命令中使用 2 个不同的 WHERE 子句但应用于单独的表吗?意思是当我加入表格时,我可以有 WHERE Table1 ( Condition ) 和 WHERE Table2 ( Condition ) 吗?

A:每个WHERE关键字只能出现一次SELECT。您可以在任何表中自由包含谓词。


另外,要回答一些您没有问的其他问题...

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

Table2 的 Date 列上的谓词似乎表示日期文字。(正如它们在您的陈述中一样,它们似乎代表一个整数值,由一系列除法运算得出。

文字应显式转换为 DATETIME(以匹配 Date 列的数据类型)。SQL Server 不需要显式 CONVERT,但如果没有转换,您确实希望将它们表示为规范(明确)格式的字符串。(“2012 年 3 月 5 日”代表 3 月 5 日还是 5 月 3 日?)

SQL Server DATTIME 数据类型存储日期和时间组件。通常,当用户询问结束日期时,他们也意味着当天的任何时间。考虑到 '2011-12-30 09:30:00' 的 DATETIME 值不是 <= '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 比较将产生不希望的结果。

(注意字符串“3/5/2011”不在“1/1/2011”和“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)
于 2012-06-22T20:01:35.673 回答
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
于 2012-06-22T19:02:17.187 回答
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

于 2012-06-22T19:07:42.740 回答