【问题标题】:Loop through table, use conditionals, then store value in another table遍历表,使用条件,然后将值存储在另一个表中
【发布时间】:2014-04-09 04:39:01
【问题描述】:

过程是根据表A中的“字母”栏填写表B中的“城市”栏。

表A

+----------+-------+  
|  Number  | Letter|  
+----------+-------+  
| 1        |   A   |  
| 1        |       |  
| 1        |       |  
| 2        |       |  
| 2        |       |  
| 3        |       |  
| 3        |   B   |
| 3        |       |
| 3        |   C   |  
+----------+-------+  

表 B

+----------+-------+  
|    AC    |  City |  
+----------+-------+  
| 1        |   A   |  
| 1        |   A   |  
| 1        |   A   |  
| 1        |   A   |  
| 2        |       |  
| 2        |       |  
| 2        |       |  
| 2        |       |  
| 3        |   B   |  
| 3        |   B   |  
| 3        |   B   |  
+----------+-------+  

如果 AC=1,则参考 Number=1,并从上到下循环遍历“字母”值以获得最高值。

对于Number=1,最高值是A,所以对于AC=1,将所有“City”列填写为A。

对于AC=2,Number=2,表A中没有数值,所以每个AC=2的“City”都填空。

对于AC=3,Number=3,最高值是B,所以每个AC=3的“城市”都填写为B。

您如何在标准 SQL 中对此进行编码?

我正在使用 Caspio 软件并将 SQL 插入到“City”列本身,但这不应该过多干扰代码。

这是我目前所拥有的:

SELECT Letter
FROM TableA 
WHERE TableA.Number = TableB.AC
AND TableA.Number != ""
LIMIT 1

但它似乎不起作用,我认为有必要遍历表 A 以找到每个 AC=Number 的 City 值。

感谢您的帮助。

编辑:

我已经找到解决办法了:

SELECT TOP 1 Letter
FROM TableA
WHERE Letter !='' AND Number=AC

谢谢。

【问题讨论】:

  • 您使用的是哪个 DBMS? (顺便说一句:您的示例 SQL 不是“标准 SQL”)
  • @a_horse_with_no_name Caspio Bridge 的后端建立在 Microsoft 的 .NET 框架和 Microsoft SQL Server 之上。
  • 您使用的是哪个版本的 MSSQL?

标签: sql sql-server


【解决方案1】:

它不起作用,因为您没有在 FROM 子句中包含 tableB 或加入它。你可以试试这个:

    SELECT Letter FROM TableA WHERE Number IN 
(SELECT AC FROM TableB WHERE City!='' AND City IS NOT NULL)
AND Letter!='' AND LETTER IS NOT NULL

【讨论】:

  • 感谢您的回复。但是如果在表 A 中的行是空白的,City 列可以是空白的。
  • 另请注意,TableA 可以有多个字母代表同一个数字
【解决方案2】:

首先,不要想到 SQL 中的“循环”,这意味着你对问题的思考是错误的。您可以使用基于集合的思维方式。

所以想想你想做什么,而不是你想怎么做。

你想update the TableB.City based on the value of TableA.Letter

UPDATE TableB
SET City = Letter
FROM
(
    SELECT Number, Letter,ROW_NUMBER () OVER ( PARTITION BY Number order by number ) AS SortOrder
    FROM TableA
    WHERE Letter IS NOT NULL AND Letter != ''
) AS A
WHERE A.SortOrder = 1 AND TableB.AC = A.number

我已经包含了Row_Number 排序,这是为了确保你得到第一个字母。请注意,您应该按您的 PK 订购,假设您有一个并假设它是 IDENTITYint

sqlFiddle

编辑 当然,你可以做一个选择。

SELECT TableB.AC, A.Letter
FROM
(
    SELECT Number, Letter,ROW_NUMBER () OVER ( PARTITION BY Number order by number ) AS SortOrder
    FROM TableA
    WHERE Letter IS NOT NULL AND Letter != ''
) AS A
    LEFT OUTER JOIN TableB.AC = A.number
WHERE A.SortOrder = 1

【讨论】:

  • 非常感谢。但是有没有办法在没有“更新”的情况下做到这一点?出于安全原因,Caspio 不支持 UPDATE。
  • @user3313955 当然,如果您没有update 权限,则不能“将值存储在另一个表中”。
  • 我将编辑后的代码放入 sqlFiddle,但收到错误消息。我会将代码直接放入 Caspio 的 City 列中,因此结果必须是 City 值。我注意到您编辑的代码有“SELECT TableB.AC, A.Letter”,但我只需要 City 列的 Letter 值。
  • @user3313955,a)您需要告诉我您遇到了什么错误以便我提供帮助,b)您不需要号码或 AC 来正确分配它吗?如果你不这样做,那么只需摆脱 TableB.AC, 并运行你的 select
  • 没关系,我有办法。 SELECT TOP 1 Letter FROM TableA WHERE Letter !='' AND Number=AC
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-26
  • 2017-04-09
  • 2016-02-26
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
相关资源
最近更新 更多