更新包含重复信息的记录中的字段值

时间:2014-09-18 16:46:17

标签: sql ms-access ms-access-2010

我有一个查询,它返回在多个Dept ...字段中包含单词“PACK”的所有记录(最多,单词“PACK”在记录中出现两次,并且在字段内单独出现) :

SELECT *
FROM
(
  SELECT s.*,
    IIf(s.DeptOne = "Pack", 1, 0) AS D1,
    IIf(s.DeptTwo = "Pack", 1, 0) AS D2,
    IIf(s.DeptThree = "Pack", 1, 0) AS D3,
    IIf(s.DeptFour = "Pack", 1, 0) AS D4,
    IIf(s.DeptFive = "Pack", 1, 0) AS D5,
    IIf(s.DeptSix = "Pack", 1, 0) AS D6,
    IIf(s.DeptSeven = "Pack", 1, 0) AS D7,
    IIf(s.DeptEight = "Pack", 1, 0) AS D8,
    IIf(s.DeptNine = "Pack", 1, 0) AS D9,
    IIf(s.DeptTen = "Pack", 1, 0) AS D10,
    IIf(s.DeptEleven = "Pack", 1, 0) AS D11,
    IIf(s.DeptTwelve = "Pack", 1, 0) AS D12,
    IIf(s.DeptThirteen = "Pack", 1, 0) AS D13,
    IIf(s.DeptFourteen = "Pack", 1, 0) AS D14,
    IIf(s.DeptFifteen = "Pack", 1, 0) AS D15,
    IIf(s.DeptSixteen = "Pack", 1, 0) AS D16,
    IIf(s.DeptSeventeen = "Pack", 1, 0) AS D17,
    IIf(s.DeptEightteen = "Pack", 1, 0) AS D18,
    IIf(s.DeptNineteen = "Pack", 1, 0) AS D19,
    IIf(s.DeptTwenty = "Pack", 1, 0) AS D20
FROM MyTable s
) m
WHERE (m.D1 + m.D2 + m.D3 + m.D4 + m.D5 + m.D6 + m.D7 + m.D8 + 
       m.D9 + m.D10 + m.D11 + m.D12 + m.D13 + m.D14 + m.D15 + 
       m.D16 + m.D17 + m.D18 + m.D19 + m.D20) > 1

查询效果很好,并返回多个Dept ...字段中包含“PACK”的所有记录。现在我需要将这些记录中的第一个“PACK”实例更改为“PACK-M”,将这些记录中的第二个“PACK”实例更改为“PACK-S”

要查看查询中返回的两条记录的图片,请转到此处: http://www.allgoodit.com/stackoverflow/result.jpg

两个记录都在不同字段中出现两次“PACK”字样。我希望将每个记录中的第一个实例 重写为“PACK-M”,第二个实例为“PACK-S”。 没有VBA,只有SQL。

2 个答案:

答案 0 :(得分:2)

我认为这应该可以解决问题。

只需在打开Recordset

的SQL语句中更改您的表名
Dim t1 As String
Dim t2 As String
Dim p1 As String
Dim p2 As String

p1 = "PACK-M"
p2 = "PACK-S"

Dim MyDB As DAO.Database
Dim rst As DAO.Recordset

Set MyDB = CurrentDb
Set rst = MyDB.OpenRecordset("SELECT * FROM PRAYING") 'Change PRAYING to your table name Or change the string to your query name


With rst
Do While Not .EOF
        For i = 0 To .Fields.Count - 1
            If .Fields(i).Value = "PACK" And t1 <> p1 Then
                .Edit
                .Fields(i).Value = "PACK-M"
                .Update
                t1 = p1
            ElseIf .Fields(i).Value = "PACK" Then
                .Edit
                .Fields(i).Value = "PACK-S"
                .Update
                t2 = p2
            End If
        Next
    .MoveNext
    t1 = ""
    t2 = ""
Loop
End With

rst.Close
Set rst = Nothing

注意:您的问题中没有任何内容表明这必须是SQL,因此如果VBA不是您应该指定的选项。

答案 1 :(得分:2)

您可以使用二进制方案来辨别值来自哪些列。

因此,例如,以您的方式使用您的查询(我为了便于输入而减少列数)

SELECT *
FROM
(
  SELECT s.*,
    IIf(s.DeptOne = "Pack", 2, 0) AS D1,
    IIf(s.DeptTwo = "Pack", 4, 0) AS D2,
    IIf(s.DeptThree = "Pack", 8, 0) AS D3,
    IIf(s.DeptFour = "Pack", 16, 0) AS D4,
    IIf(s.DeptFive = "Pack", 32, 0) AS D5,
    IIf(s.DeptSix = "Pack", 64, 0) AS D6,
    IIf(s.DeptSeven = "Pack", 128, 0) AS D7,
    IIf(s.DeptEight = "Pack", 256, 0) AS D8,
    IIf(s.DeptNine = "Pack", 512, 0) AS D9,
    IIf(s.DeptTen = "Pack", 1024, 0) AS D10
FROM MyTable s
) m
WHERE ISNUMERIC( LOG( (m.D1 + m.D2 + m.D3 + m.D4 + m.D5 + m.D6 + m.D7 + m.D8 + 
       m.D9 + m.D10 ), 2 ) + '.0e0' ) 

请注意,'WHERE'子句必须更改,因为查找大于1的和将产生误报。因此,您可以更改它以查找总和是否为2的幂。我使用基数为2的'log'函数,然后检查结果是否为整数。要检查值是否为整数,可以追加'.0e0'并检查isnumeric。

检查此link以查找此“黑客”的来源。

然后,您可以检查'sum'值以确定最小位以确定哪个列需要使用'PACKM'更新,而更大的位将是需要使用'PACKS'更新的列

*免责声明:我没有提供'更新'脚本作为我答案的一部分。我还没有测试我的'SELECT'语句和'WHERE'逻辑。我只是希望我提供了足够的解释,通过一些可靠的推理指出你在适当的方向。希望这会对你有所帮助。