如何识别4列中行数最低的文本值?

时间:2013-05-24 17:14:03

标签: sql excel ms-access text

我发现一些文章很接近,但与我想要做的不一样。我有一个包含4列重复数据的Excel文件,每列都根据来自不同工作表的数值进行排序。 我需要识别25个(或左右)行,其中四列的值匹配,行ID最低。将有大约250行数据进行筛选,所以我只需要前10%。 我不必这样接近它。如果无法在Excel中执行此操作,我可以将此数据转储到Access中。或者我可以在每个文本列旁边分配列(为第1,2,3和4列中的每个字段分配ID的方法)并使用这些值。只要结果有效,这种方法是可以商量的。 以下是我在Excel中的数据:

     A      B      C      D
    abc    bcd    abc    def
    cde    fgh    def    bcd
    def    def    bcd    abc
    bcd    hji    xyz    lmn

所以在这种情况下,我想要突出显示(或以某种方式识别)值“def”,因为它看起来最接近所有4列的顶部,因此它具有最低的行ID。值“bcd”将在列表中排在第二位,因为它也在所有4中被标识并且具有低行ID。 任何建议,将不胜感激。我非常了解SQL,所以如果你认为将它转储到数据库中是最好的,你可以建议一个非常棒的查询。但理想情况下......将它保存在Excel中对我来说是最少量的工作。我对公式,条件格式等持开放态度。 谢谢!

3 个答案:

答案 0 :(得分:1)

思考我提出了一个相当酷的解决方案......

因此,假设您在A-D列中有这些数据,从单元格A2开始,比如说。

现在,您知道如果它们已存在于A列中,您只需要值 - 否则它们不在所有4列中。

所以:

  • 在E2中,输入公式=Row() - 这基本上表示A的值所在位置
  • 在F2中输入=Match($A2,B:B,0) - 这将在B列中找到A2值的第一个匹配项
  • 将该公式拖到G2& H2(分别在C& D中找到A2值的第一个匹配)。
  • 在I2中,输入公式=Sum(E2:H2)

现在,将E:H向下拖动整个数据集。

因此,如果H = #N/A,则表示值不在所有4列中 并且H的值越低,匹配的等级越低 - (列A的文本是您匹配的值)。

现在您可以按照H栏等排序,以满足您的需求。

希望这可以解决问题(并且有意义)!

酷Q,BTW !!!

答案 1 :(得分:0)

您是否拥有或可以创建所有可能的单元格值的主列表?如果是这样,那么对于每个唯一的单元值,4个数据列中的每一个上的一些简单VLOOKUP可以给出每列中的行号。加上4个reesults并对总数进行排序。

如果您没有唯一值的主列表,我倾向于转到Access,因为这是一组非常简单的查询,可以获得您想要的内容。

答案 2 :(得分:0)

需要澄清

当我第一次提出这个答案时,我使用了John在他聪明的Excel答案中使用的相同方法,即使用每列最小行数的总和来产生排名。这会在问题中生成样本结果,但请考虑以下修改后的测试数据:

F1   F2   F3   F4   RowNum
---  ---  ---  ---  ------
XXX  bar  baz  bat       1
foo  XXX  baz  bat       2
YYY  bar  XXX  bat       3
foo  YYY  baz  bat       4
foo  bar  YYY  bat       5
foo  bar  baz  YYY       6
foo  bar  baz  bat       7
foo  bar  baz  bat       8
foo  bar  baz  bat       9
foo  bar  baz  XXX      10

XXX出现在第1,2,3和10行中,因此总和将为16. YYY出现在第3,4,5和6行中,因此总和将为18.按总和排名将声明XXX为获胜者,即使你从第1行开始扫描XXX,你也必须一直到第10行才能到达最后的XXX,而如果你从第1行开始扫描YYY,你只需要去第6行到第到达最后一个YYY。

在这种情况下,YYY实际上应该是赢家吗?


(原始答案)

以下代码将Excel数据导入Access并添加[RowNum]列

Sub ImportExcelData()
On Error Resume Next  '' in case it doesn't already exist
DoCmd.DeleteObject acTable, "ExcelData"
On Error GoTo 0
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel12Xml, "ExcelData", "C:\Users\Gord\Documents\ExcelData.xlsx", False
CurrentDb.Execute "ALTER TABLE ExcelData ADD COLUMN RowNum AUTOINCREMENT(1,1)", dbFailOnError
End Sub

现在我们在Access中有一个[ExcelData]表,就像这样

F1   F2   F3   F4   RowNum
---  ---  ---  ---  ------
abc  bcd  abc  def       1
cde  fgh  def  bcd       2
def  def  bcd  abc       3
bcd  hji  xyz  lmn       4

让我们在Access中创建一个名为ExcelItems的已保存查询,以便在长“列表”中输入字符串......

SELECT F1 AS Item, RowNum, 1 AS ColNum FROM ExcelData
UNION ALL
SELECT F2 AS Item, RowNum, 2 AS ColNum FROM ExcelData
UNION ALL
SELECT F3 AS Item, RowNum, 3 AS ColNum FROM ExcelData
UNION ALL
SELECT F4 AS Item, RowNum, 4 AS ColNum FROM ExcelData

...返回...

Item  RowNum  ColNum
----  ------  ------
abc        1       1
cde        2       1
def        3       1
bcd        4       1
bcd        1       2
fgh        2       2
def        3       2
hji        4       2
abc        1       3
def        2       3
bcd        3       3
xyz        4       3
def        1       4
bcd        2       4
abc        3       4
lmn        4       4

现在我们可以找到每个ColNum找到Item的最低RowNum ...

TRANSFORM Min(ExcelItems.[RowNum]) AS MinOfRowNum
SELECT ExcelItems.[Item]
FROM ExcelItems
GROUP BY ExcelItems.[Item]
PIVOT ExcelItems.[ColNum] In (1,2,3,4);

...返回...

Item  1  2  3  4
----  -  -  -  -
abc   1     1  3
bcd   4  1  3  2
cde   2         
def   3  3  2  1
fgh      2      
hji      4      
lmn            4
xyz         4 

如果我们将该查询保存为ExcelItems_Crosstab,那么我们可以使用它来对所有四列中显示的项目进行排名:

SELECT Item, [1]+[2]+[3]+[4] AS Rank
FROM ExcelItems_Crosstab
WHERE ([1]+[2]+[3]+[4]) IS NOT NULL
ORDER BY 2

...返回...

Item  Rank
----  ----
def      9
bcd     10