【问题标题】:Counting the number of join symptoms计算加入症状的数量
【发布时间】:2015-08-23 06:12:37
【问题描述】:

我正在尝试做一些在其他语言中非常简单但在 SQL 中证明相当令人费解的事情。

我有一个数据库,其中患者 ID 为行,100 个症状为列。症状是二元的,0 或 1,如果患者有或没有。假设患者 1 有 0, 1, 1, ... 用于咳嗽、打喷嚏、头痛等。患者 2 类似地具有症状 1、0、1、...的二进制列表。

我想要做的只是生成一个表格,其中包含具有该症状组合的患者数量的成对症状计数。

所以当我在新表中抬头时,我可以看到有多少人同时打喷嚏和咳嗽。有多少人同时有头痛和打喷嚏等等。只能成对。如果我查看打喷嚏和打喷嚏,它会让我回到打喷嚏的人数。类似于行和列中症状的矩阵格式以及内容中患有该症状的患者数量。

使用 for 循环,这在任何其他语言中都非常容易。不过,我是 SQL 新手,正在努力寻找一种有效的方法来做到这一点。

【问题讨论】:

  • 这是什么数据库? SQL Server?
  • 是的,正是一个以 I 和 j 为症状的矩阵。
  • 如果你可以控制结构,我建议创建一个表格来保存症状
  • 最佳解决方案因 DBMS 而异,您似乎忽略了 Donal 关于它是哪一个的问题。如果你想要一个答案,你需要用供应商标记你的问题,最好是你正在使用的数据库版本
  • 关键是对您的数据进行反透视,以便每个患者的每个症状都有一行,然后将此数据连接到自身以获得成对的症状,然后将连接的数据向上透视以获取您的计数。由于我不知道要使用哪个 DBMS,我无法回答这个问题,但我创建了一个 working demo in SQL Server 来演示如何操作。

标签: sql data-analysis


【解决方案1】:

您的问题需要编写函数并在其中使用游标。

但是,还有一种替代方法:

假设您有一个包含四列的表格:

a   b   c   d
-------------------------
1   0   1   1
1   1   0   0
0   0   1   0
0   0   0   1
1   1   1   1
0   1   0   1
1   0   1   0
0   1   1   1
0   0   1   1
1   0   1   0

这是一个答案:

Select sum(a) as a_a, 
    (select count(*) from patients where a=1 and b=1 as a_b) as a_b, 
    (select count(*) from patients where a=1 and c=1 as a_c) as a_c, 
    (select count(*) from patients where a=1 and d=1 as a_d) as a_d, 
    sum(b) as b_b, 
    (select count(*) from patients where b=1 and c=1 as b_c) as b_c, 
    (select count(*) from patients where b=1 and d=1 as b_d) as b_d, 
    sum(c) as c_c, 
    (select count(*) from patients where c=1 and d=1 as c_d) as c_d, 
    sum(d) as d_d 

现在,结果是这样的:

a_a     a_b     a_c     a_d     b_b     b_c     b_d     c_c     c_d     d_d
-------------------------------------------------------------------------
5       2       3       2       4       2       2       7       4       6

它不像矩阵;它只有一排,但它拥有您想要的一切。您可以将其扩展为您自己的包含许多字段的表格。

【讨论】:

  • 谢谢...问题是列表有 100 种症状,我想尝试多个列表,因此试图避免手动逐一输入。
【解决方案2】:

您想研究不同症状之间的相互作用,对吧?

在这种情况下,最好得到不同症状之间的相关性,SQL 不适合这个问题;您需要将表格转换为csv文件,然后使用R(甚至excel),您可以获得相关性。

假设这是您的 CSV 文件 (C:/dataFile.csv):

a, b, c, d, e, f
----------------
1, 1, 1, 0, 1, 0
1, 1, 0, 1, 1, 1
0, 0, 0, 1, 0, 0
0, 1, 1, 0, 1, 0
1, 0, 0, 0, 1, 0
0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0
1, 1, 0, 1, 1, 1

现在,在 R Statistics 中,您可以一一运行以下命令:

> data <- read.csv("C:/dataFile.csv")
> summary(data)
> cor(data)

结果如下:

          a         b          c           d          e          f
a 1.0000000 0.5000000  0.0000000  0.25819889 0.77459667  0.5773503
b 0.5000000 1.0000000  0.5773503  0.25819889 0.77459667  0.5773503
c 0.0000000 0.5773503  1.0000000 -0.44721360 0.44721360 -0.3333333
d 0.2581989 0.2581989 -0.4472136  1.00000000 0.06666667  0.7453560
e 0.7745967 0.7745967  0.4472136  0.06666667 1.00000000  0.4472136
f 0.5773503 0.5773503 -0.3333333  0.74535599 0.44721360  1.0000000

具有较高相关性的两种症状意味着这两种症状主要是一起变化的。例如,[a and e] 或 [b and e] 高度相关。

我希望这能让您更广泛地了解如何处理数据分析。

【讨论】:

  • 谢谢,问题是R的数据太大了。
  • R 专为大数据而设计!它有多大?有多少条记录?
  • “pbdNCDF4 包允许多个进程写入同一个文件(无需手动同步)并支持 TB 大小的文件。”引用自:cran.r-project.org/web/views/HighPerformanceComputing.html
  • 理论上,R 支持多达 20 亿个元素(20,000,000 条记录,每条记录 100 列)。但是,如果你的机器变慢了,那么你可以安装一些 R 包:stackoverflow.com/questions/9984283/…
  • 有趣,谢谢 - 我不知道。不过,我的记录大约有 50 亿条。
【解决方案3】:

@GarethD 的这个回答帮助解决了这个问题:谢谢!

关键是对您的数据进行反透视,以便每个患者的每个症状都有一行,然后将此数据连接到自身以获得成对的症状,然后将连接的数据向上透视以获取您的计数。由于我不知道要使用哪个 DBMS,所以我无法回答这个问题,但是我创建了一个 working demo in SQL Server 来演示如何操作。 – GarethD 昨天

【讨论】:

    猜你喜欢
    • 2022-07-11
    • 2020-10-24
    • 1970-01-01
    • 2012-12-10
    • 2015-08-18
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 2012-11-03
    相关资源
    最近更新 更多